2013-05-28 48 views
3

我想搜索嵌套文档的数组,并只返回符合特定条件的文档。在ElasticSearch中返回部分嵌套文档

一个例子映射是:

{"book": 
    {"properties": 
     { 
     "title":{"type":"string"}, 
     "chapters":{ 
        "type":"nested", 
        "properties":{"title":{"type":"string"}, 
            "length":{"type":"long"}} 
            } 
        } 
      } 
    } 
} 

所以,说我要寻找名为“尾声”等章节。 并不是所有的书都有这样的章节,但是如果我使用嵌套查询,那么我会得到一本书中的所有章节,其中具有这样的章节。尽管我感兴趣的是那些拥有这样一个标题的章节。

我主要关心I/O和网络流量,因为可能有很多章节。

此外,有没有办法只检索嵌套的文件,没有包含文档?

+0

不是章节总是嵌套在书籍对象下? – concept47

+0

您不能使用嵌套文档afaik。然而,你可以将它改造成父母(书) - 儿童(章)关系。在这种情况下,您的问题+答案类似于http://stackoverflow.com/questions/7431889/how-can-i-retrieve-matching-children-only –

+1

github上的相关问题,以便能够返回匹配的嵌套 - 上下文︰https://github.com/elasticsearch/elasticsearch/issues/1383和较新的https://github.com/elasticsearch/elasticsearch/issues/3022 –

回答

4

这是我偶然发现的一个非常古老的问题,所以我将展示两种不同的方法来解决这个问题。

让我们先准备指数和一些测试数据:

PUT /bookindex 
{ 
    "mappings": { 
    "book": { 
     "properties": { 
     "title": { 
      "type": "string" 
     }, 
     "chapters": { 
      "type": "nested", 
      "properties": { 
      "title": { 
       "type": "string" 
      }, 
      "length": { 
       "type": "long" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

PUT /bookindex/book/1 
{ 
    "title": "My first book ever", 
    "chapters": [ 
    { 
     "title": "epilogue", 
     "length": 1230 
    }, 
    { 
     "title": "intro", 
     "length": 200 
    } 
    ] 
} 

PUT /bookindex/book/2 
{ 
    "title": "Book of life", 
    "chapters": [ 
    { 
     "title": "epilogue", 
     "length": 17 
    }, 
    { 
     "title": "toc", 
     "length": 42 
    } 
    ] 
} 

现在,我们已经在Elasticsearch这些数据,我们可以检索只是使用inner_hits相关命中。这种方法非常简单,但我更喜欢最后概述的方法。

# Inner hits query 
POST /bookindex/book/_search 
{ 
    "_source": false, 
    "query": { 
    "nested": { 
     "path": "chapters", 
     "query": { 
     "match": { 
      "chapters.title": "epilogue" 
     } 
     }, 
     "inner_hits": {} 
    } 
    } 
} 

inner_hits嵌套查询返回的文档,其中每个命中包含与所有的匹配的文档,其中包括计分信息的一个inner_hits对象。你可以看到response

我对此类查询的首选方法是使用nested aggregationfiltered子聚合,其中包含top_hits子聚合。查询看起来像:

# Nested and filter aggregation 
POST /bookindex/book/_search 
{ 
    "size": 0, 
    "aggs": { 
    "nested": { 
     "nested": { 
     "path": "chapters" 
     }, 
     "aggs": { 
     "filter": { 
      "filter": { 
      "match": { "chapters.title": "epilogue" } 
      }, 
      "aggs": { 
      "t": { 
       "top_hits": { 
       "size": 100 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

top_hits子聚集是一个中 别人做实际的检索嵌套文档的 和支持fromsize性能。从文档:

如果top_hits聚合包装在nestedreverse_nested 聚合,然后被返回嵌套命中。嵌套命中是 意义隐藏迷你文档是常规文档的一部分,其中 已配置嵌套字段类型的映射。如果聚合器在nestedreverse_nested聚合器中被包装为 ,那么聚合器能够取消隐藏这些文档。详细了解嵌套在 中的嵌套类型映射。

response from Elasticsearch是(IMO)更漂亮(它似乎更快地返回(虽然这不是科学观察))并且“更容易”解析。

相关问题