3

我有文件,如下所示:

{
    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}"));
4

1 回答 1

3

我建议在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()

使用一些示例文档,时间序列看起来像这样,这似乎是您正在寻找的。

用户在线

于 2017-07-28T06:16:38.480 回答