我们试图在Elasticsearch中找到不同的内部对象。对于我们的情况来说,这将是一个最小的例子。我们被以下映射所困扰(更改类型或索引或添加新字段不是问题,但结构应该保持原样):
{
"building": {
"properties": {
"street": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
},
"house number": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
},
"city": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
},
"people": {
"type": "object",
"store": "yes",
"index": "not_analyzed",
"properties": {
"firstName": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
},
"lastName": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
}
}
}
}
}
}假设我们有这个示例数据:
{
"buildings": [
{
"street": "Baker Street",
"house number": "221 B",
"city": "London",
"people": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Jane",
"lastName": "Doe"
}
]
},
{
"street": "Baker Street",
"house number": "5",
"city": "London",
"people": [
{
"firstName": "John",
"lastName": "Doe"
}
]
},
{
"street": "Garden Street",
"house number": "1",
"city": "London",
"people": [
{
"firstName": "Jane",
"lastName": "Smith"
}
]
}
]
}当我们查询街道“贝克街”(以及所需的任何其他选项)时,我们希望得到以下列表:
[
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Jane",
"lastName": "Doe"
}
]格式并不重要,但是我们应该能够解析名字和姓氏。只是,由于我们的实际数据集要大得多,我们需要的条目是不同的。
我们正在使用Elasticsearch 1.7。
发布于 2015-10-27 12:24:49
我们终于解决了问题。
我们的解决方案是(正如我们预期的)一个预先计算的people_all字段.但是,我们不是使用copy_to或transform,而是在导入数据时编写其他字段。该领域如下:
"people": {
"type": "nested",
..
"properties": {
"firstName": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
},
"lastName": {
"type": "string",
"store": "yes",
"index": "not_analyzed"
},
"people_all": {
"type": "string",
"index": "not_analyzed"
}
}
}请注意"index": "not_analyzed"在people_all字段。这是重要的,有完整的桶。如果您不使用它,我们的示例将返回3个桶"john“、"jane”和"doe“。
在编写完这个新字段之后,我们可以按以下方式运行一个扩展:
{
"size": 0,
"query": {
"term": {
"street": "Baker Street"
}
},
"aggs": {
"people_distinct": {
"nested": {
"path": "people"
},
"aggs": {
"people_all_distinct": {
"terms": {
"field": "people.people_all",
"size": 0
}
}
}
}
}
}我们将返回以下答复:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0.0,
"hits": []
},
"aggregations": {
"people_distinct": {
"doc_count": 3,
"people_name_distinct": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "John Doe",
"doc_count": 2
},
{
"key": "Jane Doe",
"doc_count": 1
}
]
}
}
}
}从响应中的桶中,我们现在能够创建不同的人员对象。
请告诉我们是否有更好的方法来达到我们的目标。解析桶不是一个最优的解决方案,如果每个桶中都有字段firstName和lastName,那就更好了。
发布于 2015-10-26 17:24:54
正如注释中所建议的那样,您对人员的映射应该是nested类型,而不是object类型,因为它可能会产生意想不到的结果。在此之后,还需要重新编制数据索引。
至于这个问题,您需要根据您的查询来聚合结果。
{
"query": {
"term": {
"street": "Baker Street"
}
},
"aggs": {
"distinct_people": {
"terms": {
"field": "people",
"size": 1000
}
}
}
}请注意,我已经将size设置为1000内部聚合,您可能需要使用更大的数字来获取所有不同的人,ES默认只返回10个结果。
如果您只对聚合桶感兴趣,可以将查询size设置为0,或者使用参数search_type=count。您可以在这里阅读更多关于聚合的内容。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
我希望这能帮上忙!如果这件事没有解决,请告诉我。
https://stackoverflow.com/questions/33349315
复制相似问题