2015-05-05 135 views
0

我有一个名为properties的数组的对象。属性本身就是对象,由字段属性和值组成(以及其他一些在此不重要的属性)。如何在弹性搜索中聚合数组中的匹配字段

我想查找某个属性的所有值。

我目前的做法是为properties.attribute使用过滤查询,然后使用properties.value聚合。但是这个不足,因为聚合使用了所有定义的属性,而不仅仅是那些带有搜索的属性。属性的属性。

是否有一种方法可以将聚合“空间”限制为properties.attribute所匹配的属性?

为了完整起见,这里发现了许多价值卷曲电话,我只在“FARBE”感兴趣的(颜色):

curl -XGET 'http://localhost:9200/pwo/Product/_search?size=0&pretty=true' -d '{ 
"query": { 
    "filtered": { 
    "query": { "match_all" : { } }, 
    "filter": { 
     "bool": { 
     "must": { "term": { "properties.attribute": "farbe" } } 
     } 
    } 
    } 
}, 
"aggregations": { 
    "properties": { 
    "terms": { "field": "properties.value" } 
    } 
} 
}' 

回答

1

nested aggregationfilter aggregation组合似乎做什么你想要,如果我理解正确。尽管如此,你必须将你的映射设置为nested type

作为一个玩具的例子,我建立了一个简单的指标如下:

PUT /test_index 
{ 
    "settings": { 
     "number_of_shards": 1 
    }, 
    "mappings": { 
     "doc": { 
     "properties": { 
      "properties": { 
       "type": "nested", 
       "properties": { 
        "attribute": { 
        "type": "string" 
        }, 
        "value": { 
        "type": "string" 
        } 
       } 
      } 
     } 
     } 
    } 
} 

(注意,这是一个有点混乱,因为“性”既是一个关键字和属性的定义,在这种情况下。 )

现在我可以索引几个文件:

POST /test_index/doc/_bulk 
{"index":{"_id":1}} 
{"properties":[{"attribute":"lorem","value":"Donec a diam lectus."},{"attribute":"ipsum","value":"Sed sit amet ipsum mauris."}]} 
{"index":{"_id":2}} 
{"properties":[{"attribute":"dolor","value":"Donec et mollis dolor."},{"attribute":"sit","value":"Donec sed odio eros."}]} 
{"index":{"_id":3}} 
{"properties":[{"attribute":"amet","value":"Vivamus fermentum semper porta."}]} 

然后我可以通过"properties.attribute"过滤上"properties.value"汇聚如下:

POST /test_index/_search?search_type=count 
{ 
    "aggs": { 
     "nested_properties": { 
     "nested": { 
      "path": "properties" 
     }, 
     "aggs": { 
      "filtered_by_attribute": { 
       "filter": { 
        "terms": { 
        "properties.attribute": [ 
         "lorem", 
         "amet" 
        ] 
        } 
       }, 
       "aggs": { 
        "value_terms": { 
        "terms": { 
         "field": "properties.value" 
        } 
        } 
       } 
      } 
     } 
     } 
    } 
} 

在这种情况下返回:

{ 
    "took": 3, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 3, 
     "max_score": 0, 
     "hits": [] 
    }, 
    "aggregations": { 
     "nested_properties": { 
     "doc_count": 5, 
     "filtered_by_attribute": { 
      "doc_count": 2, 
      "value_terms": { 
       "doc_count_error_upper_bound": 0, 
       "sum_other_doc_count": 0, 
       "buckets": [ 
        { 
        "key": "a", 
        "doc_count": 1 
        }, 
        { 
        "key": "diam", 
        "doc_count": 1 
        }, 
        { 
        "key": "donec", 
        "doc_count": 1 
        }, 
        { 
        "key": "fermentum", 
        "doc_count": 1 
        }, 
        { 
        "key": "lectus", 
        "doc_count": 1 
        }, 
        { 
        "key": "porta", 
        "doc_count": 1 
        }, 
        { 
        "key": "semper", 
        "doc_count": 1 
        }, 
        { 
        "key": "vivamus", 
        "doc_count": 1 
        } 
       ] 
      } 
     } 
     } 
    } 
} 

这里是我以前一起代码:

http://sense.qbox.io/gist/1e0c58aae54090fadfde8856f4f6793b68de0167

+0

非常感谢您的完整的答案,不知何故因此未通知所以我现在只看到它。在这之间,我使用了解决方法将属性作为独立类型存储在索引中,并存储了每个属性文档对原始文档的引用。但从我看到你的解决方案更清洁。 – TeTeT