比方说我有:
"hits": [
{
"_index": "products",
"_type": "product",
"_id": "599c2b3fc991ee0a597034fa",
"_score": 1,
"_source": {,
"attributes": {
"1": [
"a"
],
"2": [
"b",
"c"
],
"3": [
"d",
"e"
],
"4": [
"f",
"g"
],
"5": [
"h",
"i"
]
}
}
},
{
"_index": "products",
"_type": "product",
"_id": "599c4bb4b970c25976ced8bd",
"_score": 1,
"_source": {
"attributes": {
"1": [
"z"
],
"2": [
"y"
]
}
}
Run Code Online (Sandbox Code Playgroud)
每个产品都有属性.每个属性都有ID和值.我可以按属性过滤产品,但是现在我正在从MongoDB创建"可能的属性"列表.我想找到一种方法从ElasticSearch单独生成这样的列表(也许只是查询MongoDB以获取更多数据).
我需要的是:
{
1: [a, z],
2: [b, c, y],
etc.
}
Run Code Online (Sandbox Code Playgroud)
这样的聚合怎么样?获取所有可用的属性(按分组attribute.id)及其所有可能的值(在所有产品中)?
您不能在一个查询中完成,但在两个查询中相当容易:
您可以使用映射来获取文档中的所有字段:
curl -XGET "http://localhost:9200/your_index/your_type/_mapping"
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用多个术语聚合来获取字段的所有值:
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
}
},
...
}
}'
Run Code Online (Sandbox Code Playgroud)
这将检索每个字段的前 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"
}
},
...
}
}'
Run Code Online (Sandbox Code Playgroud)
如果没有这么多不同的属性,以前的工作。如果有,您应该更改文档的存储方式以防止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"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
将解决这个问题,您将能够在“名称”上使用术语聚合,然后在“值”上使用子术语聚合来获得您想要的:
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
}
}
}
}
}
}'
Run Code Online (Sandbox Code Playgroud)
它需要对属性使用嵌套映射。
| 归档时间: |
|
| 查看次数: |
390 次 |
| 最近记录: |