当前位置: 首页 > 面试题库 >

Elasticsearch:聚合,按字段计数

戚泰
2023-03-14
问题内容

我将此数据插入了Elasticsearch:

[
  { "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)执行:卷曲-s -XPOST ‘ 的http://本地主机:9200 /测试/外部/
_bulk漂亮 ‘ -数据二进制@
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 }
]

这是我想要的确切结果。

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


问题答案:

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

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

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'


 类似资料:
  • 问题内容: 如何编写一个将整个字段值而不是单个标记考虑在内的ElasticSearch术语聚合查询?比如,我想通过城市名聚集,但下面的回报,,并作为单独的水桶,不和的水桶预期。 问题答案: 您应该在映射中解决此问题。添加一个not_analyzed字段。如果您还需要分析的版本,则可以创建多字段。 现在在city.raw上创建聚合

  • 问题内容: 我正在尝试创建一个脚本字段,该脚本字段将计算两个时间戳之间的时间差,然后在该脚本字段上聚合一个。 我首先尝试: 在合计平均值下产生价值。 然后我尝试了: 生成了一条错误消息,内容为:“在映射中找不到[timedifference]的字段” 问题答案: 简单地将脚本移到聚合上怎么样?

  • 我是Elasticsearch的新手,我希望在Elasticsearch 5的字段上执行某些聚合。x索引。我有一个索引,其中包含带有字段(具有嵌套结构)和字段(具有嵌套结构)的文档。这些是动态映射的字段。以下是示例文档 文件2: DOC 3: 我想在langs字段上执行总和聚合,这样对于每个键(X/Y)和每种语言,我都可以获得索引中所有文档的总和。此外,我还想从docLang字段生成每种语言类型的

  • 在这里,我得到了错误: “无效的术语聚合顺序路径[price>price>price.max]。术语桶只能在子聚合器路径上排序,该路径由路径中的零个或多个单桶聚合和路径末尾的最终单桶或度量聚合组成。子路径[price]指向非单桶聚合” 如果我按持续时间聚合排序,查询可以正常工作,如 那么,有什么方法可以通过嵌套字段上的嵌套聚合来排序聚合吗?

  • 问题内容: 我想在字段上使用stats或extended_stats聚合,但是找不到完成此操作的任何示例(即,似乎只能将聚合与实际文档字段一起使用)。 是否有可能计算出“元数据”在ElasticSearch查询响应每个命中字段请求集合(例如,,,,等等)? 我假设答案是“否”,因为未对类似字段进行索引… 问题答案: 注意:就最新版本的Elasticsearch而言,原始答案现在已过时。使用Groo

  • 我看到一些关于嵌套字段和聚合的帖子,但它们似乎都没有回答我的问题。所以,如果这是一个重复的问题,请原谅,如果有任何帮助,我们将不胜感激。 我们建立了一个讲座索引,讲座具有以下特点: 讲座可以是面对面(现场)或预先录制(在线) 每个讲座可以有多个章节 这些章节中的每一个都可以由不同的讲师讲解(例如:量子物理的第一章可以由五个不同的讲师讲解,其中三个可能是现场直播,另外两个可能在线) 在线讲座每个讲师