【问题标题】:ELK query to return one record for each product with the max timestampELK 查询为每个具有最大时间戳的产品返回一条记录
【发布时间】:2017-08-31 16:43:12
【问题描述】:

在 Kibana 上,我可以查看各种产品 (product.name) 的日志以及时间戳和其他信息。这是其中一个日志:

{
  "_index": "xxx-2017.08.30",
  "_type": "logs",
  "_id": "xxxx",
  "_version": 1,
  "_score": null,
  "_source": {
    "v": "1.0",
    "level": "INFO",
    "timestamp": "2017-01-30T18:31:50.761Z",
    "product": {
      "name": "zzz",
      "version": "2.1.0-111"
    },
    "context": {
      ...
      ...
    }
  },
  "fields": {
    "timestamp": [
      1504117910761
    ]
  },
  "sort": [
    1504117910761
  ]
}

同一产品有几个其他日志,不同产品也有几个日志。

但是,我想编写一个查询,该查询返回给定 product.name 的单个记录(具有最大时间戳值的那个),并且它返回所有其他产品的相同信息。也就是说,为每个产品返回一个日志,对于每个产品,它应该是具有最大时间戳的日志。

我如何做到这一点?

我尝试遵循以下方法: How to get latest values for each group with an Elasticsearch query?

并创建了一个查询:

{
    "aggs": {
        "group": {
            "terms": {
                "field": "product.name"
            },
            "aggs": {
                "group_docs": {
                    "top_hits": {
                        "size": 1,
                        "sort": [
                            {
                                "timestamp": {
                                    "order": "desc"
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
}'

但是,我收到一条错误消息:

  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "Fielddata is disabled on text fields by default. Set fielddata=true on [product.name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
      }
    ],

在这种情况下,我绝对需要为此字段设置 fielddata=true 吗?如果没有,我该怎么办?如果是,我不确定如何设置它。我试过这样做:

curl -XGET 'localhost:9200/xxx*/_search?pretty' -H 'Content-Type: application/json' -d'
{
    "properties": {
      "product.name": { 
        "type":     "text",
        "fielddata": true
      }
    },
    "aggs": {
        "group": {
            "terms": {
                "field": "product.name"
            },
            "aggs": {
                "group_docs": {
                    "top_hits": {
                        "size": 1,
                        "sort": [
                            {
                                "timestamp": {
                                    "order": "desc"
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
}'

但是,我认为它有问题(在语法上?)并且我得到了这个错误:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "parsing_exception",
        "reason" : "Unknown key for a START_OBJECT in [properties].",
        "line" : 3,
        "col" : 19
      }
    ],

【问题讨论】:

    标签: elasticsearch elastic-stack


    【解决方案1】:

    您收到错误的原因是您尝试对文本字段 (product.name) 进行聚合,而在 elasticsearch 5 中无法做到这一点。 您不需要将字段数据设置为 true,您需要做的是在映射字段产品中定义。名称为 2 个字段,一个 product.name 和第二个 product.name.keyword 像这样:

    {
     "product.name": 
          {
             "type" "text",
              "fields":
                 {
                    "keyword": 
                       { 
                         "type": "keyword",
                         "ignore_above": 256
                        }
                 }
             }
       }
    

    那你需要对product.name.keyword做聚合

    【讨论】:

    • 松懈,我实际上只是在发布此问题后尝试将上面查询中的 "field": "product.name" 替换为 "field": "product.name.keyword" 至少不是失败并且似乎返回了正确的记录。我们真的需要像你上面写的那样使用上面的整个大部分,而不是仅仅用 product.name.keywrod 替换 product.name 吗?如果是,为什么?以及如何将其包含在上面的当前查询中?
    • 整个大部分都需要在您的架构中。请发布您的架构
    猜你喜欢
    • 2012-06-17
    • 2013-08-15
    • 2023-04-10
    • 2012-05-05
    • 2010-11-02
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多