Ряд 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()
Используя несколько примеров документов, временные ряды выглядят так, как будто вы ищете.