【问题标题】:Elastic Search: aggregation, count by field弹性搜索:聚合,按字段计数
【发布时间】:2016-09-28 15:52:31
【问题描述】:

我将此数据插入到弹性搜索中:

[
  { "name": "Cassandra Irwin",  "location": "Monzon de Campos" ..     },
  { "name": "Gayle Mooney",     "location": "Villarroya del Campo" .. },
  { "name": "Angelita Charles", "location": "Revenga de Campos" ..    }, 
  { "name": "Sheppard Sweet",   "location": "Santiago del Campo" ..   },
  ..
  ..

旁注:重现: 1) 下载:http://wmo.co/20160928_es_query/bulk.json 2)执行: curl -s -XPOST 'http://localhost:9200/testing/external/_bulk?pretty' --data-binary @bulk.json

问题:计算每个“位置”有多少条记录。

解决方案 1:桶聚合 .. 没有给出预期的结果

curl -s -XPOST 'localhost:9200/testing/_search?pretty' -d '
{
  "aggs": {  "location_count": { "terms": { "field":"location",   "size":100 }}}
}' | jq  '.aggregations'

结果:

{"location_count":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,
 "buckets":[
    {"key":"campo",     "doc_count":47},
    {"key":"del",       "doc_count":47},
    {"key":"campos",    "doc_count":29},
    {"key":"de",        "doc_count":29},
    {"key":"villarroya","doc_count":15},
    {"key":"torre",     "doc_count":12},
    {"key":"monzon",    "doc_count":11},
    {"key":"santiago",  "doc_count":11},
    {"key":"pina",      "doc_count":9},
    {"key":"revenga",   "doc_count":9},
    {"key":"uleila",    "doc_count":9}
]}}

问题:它将“位置”字段拆分为单词,并返回每个单词的文档计数。

解决方案 2:想要的结果,但担心性能。

我可以使用这个查询,提取所有位置并在 jq 中进行聚合(每个方便的 JSON cli 工具), 但是当应用于大量数据时,这可能会变成一场性能噩梦:

curl -s -XPOST 'localhost:9200/testing/_search?pretty' -d '
 {
   "query": { "wildcard": { "location": "*" } }, "size":1000,
   "_source": ["location"]
 }' | jq  '[.hits.hits[] |
           {location:._source.location,"count":1}] |
           group_by(.location) |
           map({ key: .[0].location, value: map(.count)|add })'

结果:

[
  { "key": "Monzon de Campos",      "value": 11 },
  { "key": "Pina de Campos",        "value": 9  },
  { "key": "Revenga de Campos",     "value": 9  },
  { "key": "Santiago del Campo",    "value": 11 },
  { "key": "Torre del Campo",       "value": 12 },
  { "key": "Uleila del Campo",      "value": 9  },
  { "key": "Villarroya del Campo",  "value": 15 }
]

这正是我想要的结果。

问题:如何通过弹性搜索查询获得相同的结果? (即通过弹性搜索而不是 jq 处理聚合)

【问题讨论】:

    标签: json elasticsearch


    【解决方案1】:

    您需要在location 字段中添加一个not_analyzed 子字段。

    首先像这样修改你的映射:

    curl -XPOST 'http://localhost:9200/testing/_mapping/external' -d '{
       "properties": {
          "location": {
             "type": "string",
             "fields": {
                "raw": {
                   "type": "string",
                   "index": "not_analyzed"
                }
             }
          }
       }
    }'
    

    然后再次重新索引您的数据:

    curl -s -XPOST 'http://localhost:9200/testing/external/_bulk?pretty' --data-binary @bulk.json
    

    最后,您将能够像这样运行您的查询(在location.raw 字段上)并获得您期望的结果:

    curl -s -XPOST 'localhost:9200/testing/_search?pretty' -d '
    {
      "aggs": {  "location_count": { "terms": { "field":"location.raw",   "size":100 }}}
    }' | jq  '.aggregations'
    

    【讨论】:

    • 看准了! (我尝试过这个)。非常感谢您提供非常快速和正确的答案!
    • 太棒了,很高兴它有帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-07-25
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多