2013-05-28 57 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)更漂亮(它似乎更快地返回(雖然這不是科學觀察))並且「更容易」解析。

相關問題