如何处理弹性搜索中的聚合(分组依据)

How to deal with aggregations (group by) in elasticsearch

我正在从 SQL 迁移到 elasticsearch,但我遇到了一些聚合问题,尤其是 group by

我的查询看起来像

SELECT    count(*) as total,country_code 
FROM      orders 
WHERE     product_id = ? 
GROUP BY  country_code 
ORDER BY  total desc LIMIT 3 

SQL RESULT

我试过这个但没用

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "line_items.product_id": {
                            "query": "0001112223333"
                        }
                    }
                }
            ]
        }
    },
    "from": 0,
    "size": 3,
    "aggregations": {
        "country_code": {
            "aggregations": {
                "COUNT(*)": {
                    "value_count": {
                        "field": "_index"
                    }
                }
            },
            "terms": {
                "field": "country_code",
                "size": 200
            }
        }
    }
}

ES RESULT

根据您的图像,使用 keyword 数据类型而不是 text

根据关键字link,

They are typically used for filtering (Find me all blog posts where status is published), for sorting, and for aggregations. Keyword fields are only searchable by their exact value.

您观察到这些错误的原因是因为您正在尝试 运行 对 text 数据类型进行聚合查询。文本数据类型经历 Analysis 阶段,ES 将在该阶段获取值,将其分解为标记并将它们存储在倒排索引中,

我建议您使用 multi-fields,其中 country_code 的映射如下所示:

映射:

{  
   "properties":{  
      "country_code":{  
         "type":"text",
         "fields":{  
            "keyword":{  
               "type":"keyword"
            }
         }
      }
   }
}

聚合查询:

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "line_items.product_id": {
                            "query": "0001112223333"
                        }
                    }
                }
            ]
        }
    },
    "from": 0,
    "size": 3,
    "aggregations": {
        "country_code": {
            "aggregations": {
                "COUNT(*)": {
                    "value_count": {
                        "field": "_index"
                    }
                }
            },
            "terms": { 
                "field": "country_code.keyword",          <----- change this
                "size": 200
            }
        }
    }
}

请注意我在聚合查询中使用 country_code.keyword 的上述字段。

希望对您有所帮助!

您应该考虑使用产品 ID 作为关键字而不是文本类型,然后对其使用词条查询而不是匹配查询,因为这样会更有效。此外,由于您不需要文档中的任何数据,您可以将查询的大小设置为 0。

此外,您应该在 country_code 字段的映射中使用关键字类型。

这个简单的查询应该可以完成您的工作 -

{
  "size": 0,
  "query": {
    "term": {
      "line_items.product_id": 1116463
    }
  },
  "aggregations": {
    "ad_type": {
      "terms": {
        "field": "country_code",
        "size": 200
      }
    }
  }
}

P.S。 - 也分享你的索引映射,因为它会使图片更清晰。