2015-02-11 21 views
2

是否可以通過在Elasticsearch查詢中搜索子文檔來返回父數據?從Elasticsearch返回子數據文件的父數據

我有兩種文檔類型,例如書和章,與父/子(不嵌套)相關。

我想在子文檔上運行搜索並返回子文檔,其中包含父文檔的一些字段。我試圖避免對父進行單獨的查詢。

更新

唯一可行的辦法,我能找到的是使用has_child查詢,然後一個系列片集合的鑽回孩子,然後再次申請查詢/過濾器。但是,這看起來過於複雜和低效。

GET index/_search 
{ 
    "size": 10, 
    "query": { 
    "has_child": { 
     "type": "chapter", 
    "query": { 
    "term": { 
     "field": "value" 
     } 
     } 
    } 
    }, 
    "aggs": { 
"name1": { 
    "terms": { 
    "size": 50, 
    "field": "id" 
    }, 
    "aggs": { 
    "name2": { 
     "top_hits": { 
     "size": 50 
     } 
    }, 
    "name3": { 
     "children": { 
     "type": "type2" 
     }, 
     "aggs": { 
     "docFilter": { 
      "filter": { 
      "query": { 
       "match": { 
       "_all": "value" 
       } 
      } 
      }, 
      "aggs": { 
      "docs": { 
       "top_hits": { 
       "size": 50 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 
    } 
} 
+0

你需要更具體。爲「嵌套」查詢返回的文檔確實包含「根」文檔中的字段。 – 2015-02-11 10:39:37

+0

我已經更新了原始問題和更多信息。 – 2015-02-11 10:44:18

+0

我想知道如果你找到答案。我正在查找完全相同的查詢。 – batmaci 2016-01-22 09:37:26

回答

2

有可能做一個has_child查詢,以便用top hits聚集,還給孩子文檔返回父文檔,但它是一個有點麻煩。

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html

Inner Hits功能,是由於在1.5.0被釋放會做你想要什麼。

http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/search-request-inner-hits.html

你可以建立從主源,並嘗試一下。

+0

這也是我的想法。我用'has_child'方法更新了這個問題。不幸的是我不能使用1.5,因爲它沒有被髮布和支持。 – 2015-02-11 11:26:02

0

正如Dan Tuffery在他的評論中所言,目前,這可以通過Inner Hits實現,在Java中,您可以通過下一代碼片段更容易理解它。

SearchResponse searchResponse = this.transportClient.prepareSearch("your_index") 
       .setTypes("your_type") 
       .setQuery(QueryBuilders.filteredQuery(
           null, 
           FilterBuilders.hasParentFilter(
             "parent_type_name", 
             FilterBuilders.termFilter("foo", "foo")) 
           .innerHit(new QueryInnerHitBuilder())) 
       ) 
       .execute().actionGet(); 

List<YourObject> list = new ArrayList<>(); 

for (SearchHit searchHit : searchHits.getHits()) { 

    YourObject yourObject = this.objectMapper.readValue(searchHit.getSourceAsString(), YourObject.class); 
    yourObject.setYourParentObject(this.objectMapper.readValue(searchHit.getInnerHits().get("parent_type_name").getAt(0).getSourceAsString(), YourParentObject.class)); 

    list.add(yourObject); 
}