让我说我有:
"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"
]
}
}
每个产品都有属性。每个属性都有ID和值。我可以按属性过滤产品,但是现在我正在从MongoDB创建“可能的属性”列表。我想找到一种方法来单独从ElasticSearch生成这样的列表(也许只是查询MongoDB以获取更多数据)。
我需要的是:
{
1: [a, z],
2: [b, c, y],
etc.
}
这样的聚合怎么样?获取所有可用的属性(按attribute.id
分组)及其所有可能的值(在所有产品中)?
答案 0 :(得分:4)
您无法在一个查询中执行此操作,但在两个查询中相当容易:
您可以使用映射来获取文档中的所有字段:
std::vector<int> populate(std::vector<int> ary, int a)
{
for (int i = 1; i <= a; i++)
{
if (i % 2 != 0)
{
ary.push_back(i);
}
}
return ary;
}
int main()
{
std::vector<int> loli(100);
for (int value : populate(loli, 31))
{
std::cout << value << " ";
system("pause");
}
}
然后,您可以使用多个Terms aggregation来获取字段的所有值:
curl -XGET "http://localhost:9200/your_index/your_type/_mapping"
这将检索每个字段的前20个最常用值。
这个20个值的限制是一个限制,以防止一个巨大的响应(如果您有几十亿个文档具有唯一的字段)。你可以修改&#34;尺寸&#34;术语聚合的参数增加它。根据您的要求,我猜选择比每个字段所采用的不同值的数量的粗略估计大10倍的东西应该可以做到。
您还可以使用cardinality aggregation执行中间查询以获取此实际值,然后将其用作术语聚合的大小。请注意,对于大数字而言,基数是一种估计值,因此您可能希望使用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
}
},
...
}
}'
。
cardinality * 2
如果没有那么多不同的属性,之前的作品。 如果有,您应该更改文档的存储方式以防止Mapping explosion,
像这样存储它们:
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"
}
},
...
}
}'
可以解决问题,您可以在&#34; name&#34;上使用术语聚合。然后是&#34;值&#34;上的子项聚合得到你想要的东西:
{
"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"
]
}
]
}
需要使用Nested mapping作为属性。