在弹性搜索中聚合值数组

Posted

技术标签:

【中文标题】在弹性搜索中聚合值数组【英文标题】:Aggregating array of values in elasticsearch 【发布时间】:2014-12-31 19:39:08 【问题描述】:

我需要如下聚合一个数组

两个文档示例:


    "_index": "log",
    "_type": "travels",
    "_id": "tnQsGy4lS0K6uT3Hwzzo-g",
    "_score": 1,
    "_source": 
        "state": "saopaulo",
        "date": "2014-10-30T17",
        "traveler": "patrick",
        "registry": "123123",
        "cities": 
            "saopaulo": 1,
            "riodejaneiro": 2,
            "total": 2
        ,
        "reasons": [
            "Entrega de encomenda"
        ],
        "from": [
            "CompraRapida"
        ]
    
,

    "_index": "log",
    "_type": "travels",
    "_id": "tnQsGy4lS0K6uT3Hwzzo-g",
    "_score": 1,
    "_source": 
        "state": "saopaulo",
        "date": "2014-10-31T17",
        "traveler": "patrick",
        "registry": "123123",
        "cities": 
            "saopaulo": 1,
            "curitiba": 1,
            "total": 2
        ,
        "reasons": [
            "Entrega de encomenda"
        ],
        "from": [
            "CompraRapida"
        ]
    
,

我想聚合cities 数组,以找出所有citiestraveler 都去了。我想要这样的东西:


    "traveler":
        "name":"patrick"
    ,
    "cities":
        "saopaulo":2,
        "riodejaneiro":2,
        "curitiba":1,
        "total":3
    

其中totalcities 数组的长度减1。我尝试了术语聚合和总和,但无法输出所需的输出。

可以对文档结构进行更改,因此如果有任何类似的内容对我有帮助,我会很高兴知道。

【问题讨论】:

您是否有可以共享的该索引的映射? 【参考方案1】:

在上面发布的文档中“cities”不是一个json数组,它是一个json对象。 如果可以更改文档结构,我会将文档中的城市更改为对象数组

示例文档:

 cities : [
   
     "name" :"saopaulo"
     "visit_count" :"2",

   ,
   
     "name" :"riodejaneiro"
     "visit_count" :"1",

   
]

然后您需要在索引映射中将城市设置为 nested 类型

   "mappings": 
         "<type_name>": 
            "properties": 
               "cities": 
                  "type": "nested",
                  "properties": 
                     "city": 
                        "type": "string"
                     ,
                     "count": 
                        "type": "integer"
                     ,
                     "value": 
                        "type": "long"
                     
                  
               ,
               "date": 
                  "type": "date",
                  "format": "dateOptionalTime"
               ,
               "registry": 
                  "type": "string"
               ,
               "state": 
                  "type": "string"
               ,
               "traveler": 
                  "type": "string"
               
            
         
      

之后,您可以使用nested aggregation 获取每个用户的城市数量。 查询将在以下几行中显示:


   "query": 
      "match": 
         "traveler": "patrick"
      
   ,
   "aggregations": 
      "city_travelled": 
         "nested": 
            "path": "cities"
         ,
         "aggs": 
            "citycount": 
               "cardinality": 
                  "field": "cities.city"
               
            
         
      
   

【讨论】:

但是,我在第 30 天和第 31 天访问过它,这不会重复计算“saopaulo”吗? @PatrickVillela 是的,我误解了我使用基数编辑答案的问题elasticsearch.org/guide/en/elasticsearch/reference/current/… 给出了所需不同城市的总数,但是必须减去 -1 才能占总数,可能是总数无论如何都不应该是“城市”对象/字段的一部分,并且应该是外部的单独字段 你好。抱歉我的延误,但我不得不为另一个问题设计一个解决方案。我可能会在本周晚些时候回到这个。不过,我认为它可能会起作用......

以上是关于在弹性搜索中聚合值数组的主要内容,如果未能解决你的问题,请参考以下文章

应用聚合后过滤掉弹性搜索中的术语聚合桶

将聚合限制为弹性搜索中的热门内容

除了依靠弹性搜索聚合之外,如何获取其他数据?

如何在弹性搜索的过滤器聚合中引用多个嵌套级别?

是否有可能对弹性搜索中的热门命中结果进行聚合?

ElasticSearch 聚合函数