Ряд Timelion от совокупной суммы длины массива

У меня есть документы, похожие на приведенные ниже:

{
    dateTime: /* My time field */,
    message: {
        users: ['1', '2']
    },
    messageType: 'test'
}

Я хотел бы построить диаграмму серии Timelion, которая показывает мне накопленную сумму подсчета массива message.users, Моим первым предположением было создать скрипт:

if(doc.containsKey('message.users')) {
    return doc['message.users'].length;
} else {
    return 0;
}

Из того, что я мог сказать, doc.containsKey('message.users') всегда был ложным, что говорит мне о том, что он не был правильно проиндексирован. Я пробовал многочисленные Timelion, но все безрезультатно:

.es(index=logstash-*,timefield='dateTime',q='messageType:UserList').label('Users Online')

Я индексирую свой документ через C# NEST API следующим образом:

elasticClient.Index(
    new
    {
        DateTime = DateTime.Now,
        Message = evt.EventArgs.Message,
    },
    idx => idx.Index($"logstash-{evt.MessageCode}"));

1 ответ

Я предлагаю добавить еще одно поле под названием userCount к вашим документам, так что вам не нужно связываться со скриптами (+ это будет более производительным).

Итак, ваши документы должны выглядеть так:

{
    dateTime: /* My time field */,
    message: {
        users: ['1', '2']
    },
    userCount: 2,                  <--- add this field
    messageType: 'test'
}

Решение 1:

Вам нужно немного изменить код:

elasticClient.Index(
    new
    {
        DateTime = DateTime.Now,
        Message = evt.EventArgs.Message,
        UserCount = evt.EventArgs.Message.Users.Length
    },
    idx => idx.Index($"logstash-{evt.MessageCode}"));

Решение 2:

Если вы используете ES 5, вы можете использовать Ingest API для создания конвейера, который автоматически добавит userCount поле для вас. Вам не нужно ничего менять в своем коде.

PUT _ingest/pipeline/user-count-pipeline
{
  "description" : "Creates a new userCount field",
  "processors" : [
    {
      "script": {
        "lang": "painless",
        "inline": "ctx.userCount = ctx.message?.users?.size() ?: 0"
      }
    }
  ]
}

Тогда в Timelion будет очень легко наметить то, что вам нужно, используя metric='sum:userCount' суммировать userCount ценности и cusum() функция, чтобы получить совокупную сумму userCountчерез некоторое время. Все выражение будет выглядеть так:

.es(index=logstash-*,timefield='dateTime',q='messageType:UserList',metric='sum:userCount').label('Users Online').cusum()

Используя несколько примеров документов, временные ряды выглядят так, как будто вы ищете.

Пользователи онлайн

Другие вопросы по тегам