您无法在一个查询中做到这一点,但在两个查询中却很简单:
检索属性列表
您可以使用映射来获取文档中的所有字段:
curl -XGET "http://localhost:9200/your_index/your_type/_mapping"
检索他们的价值
然后,您可以使用多个术语聚合来获取字段的所有值:
curl -XGET "http://localhost:9200/your_index/your_type/_search" -H 'Content-Type: application/json' -d'{ "size": 0, "aggs": { "field1Values": { "terms": { "field": "field1", "size": 20 } }, "field2Values": { "terms": { "field": "field2", "size": 20 } }, "field3Values": { "terms": { "field": "field3", "size": 20 } }, ... }}'这将检索每个字段的前20个最常出现的值。
限制为20个值是防止产生巨大响应的限制(例如,如果您有数十亿个具有唯一字段的文档)。您可以修改术语聚合的“大小”参数以增加它。根据您的要求,我想选择一个比每个字段获取的不同值的数量的大致估计大10倍的方法可以解决问题。
如何处理价值的巨大基数
您还可以使用基数聚合进行中间查询,以获取此实际值,然后将其用作术语聚合的大小。请注意,基数不是一个大数的估计值,因此您可能想使用
cardinality* 2。
curl -XGET "http://localhost:9200/your_index/your_type/_search" -H 'Content-Type: application/json' -d'{ "size": 0, "aggs": { "field1Cardinality": { "cardinality": { "field": "field1" } }, "field2Cardinality": { "cardinality": { "field": "field2" } }, "field3Cardinality": { "cardinality": { "field": "field3" } }, ... }}'如何处理价值的巨大基数
如果没有太多不同的属性,则前一种方法适用。如果有的话,您应该更改文档的存储方式,以防止Mapping爆炸,
像这样存储它们:
{ "attributes":[ { "name":"1", "value":[ "a" ] }, { "name":"2", "value":[ "b", "c" ] }, { "name":"3", "value":[ "d", "e" ] }, { "name":"4", "value":[ "f", "g" ] }, { "name":"5", "value":[ "h", "i" ] } ]}将解决此问题,您将能够在“名称”上使用术语汇总,然后在“值”上使用子术语汇总来获得所需的内容:
curl -XGET "http://localhost:9200/your_index/your_type/_search" -H 'Content-Type: application/json' -d'{ "size": 0, "aggs": { "attributes": { "terms": { "field": "attributes.name", "size": 1000 }, "aggs": { "values": { "terms": { "field": "attributes.value", "size": 100 } } } } }}'它要求对属性使用嵌套映射。



