2013-09-16 196 views
5

我使用spring-data-elasticsearch和elasticsearch一起查詢文檔。我想對嵌套文檔進行嵌套查詢。春季數據彈性搜索與嵌套字段和映射

我有這個在java中:

@Document(indexName = "as", type = "a", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1") 
class A { 

    @Id 
    private String Id; 

    @Field(type = String, index = analyzed, store = true) 
    private String field1; 

    // ... Many more Fields. 

    @NestedField(type = FieldType.Object, index = analyzed, store = true, dotSuffix = "accounts") 
    private List<B> bs; 

    // ... getters and setters 
} 

而且

class B { // some normal pojo } 

當我讓Spring數據進行映射,我得到:

"a": { 
    "properties": { 
     "bs": { 
      "properties": { 
       "someBProperty": { 
        "type": "string" 
       }, 
       "BId": { 
        "type": "string" 
       } 
      } 
     }, 
     "id": { ... }, 
     ... 
} 

當我試圖查詢文檔,我得到經典的內部vs嵌套文檔問題,它不識別嵌套元素。

當我嘗試更新映射以使用嵌套文檔時,我得到「無法從非嵌套變爲嵌套」。

我應該告訴spring-data-es以某種方式將@NestedField =>類型:「嵌套」到映射中嗎?有沒有辦法在創建索引&映射時將自定義映射添加到彈簧數據?

此外,我通過初始化索引:

elasticsearchTemplate.deleteIndex(A.class); 
elasticsearchTemplate.createIndex(A.class); 
elasticsearchTemplate.putMapping(A.class); 
elasticsearchTemplate.refresh(A.class,true); 

,然後用彈簧的數據倉庫查詢:

QueryBuilder builder = QueryBuilders.nestedQuery("bs", QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("as.field1", "A1")).must(QueryBuilders.matchQuery("as.field2", "B1"))); 

Iterable<DenormalizedRelationshipDocument> res = aRepository.search(builder); 

這裏的水庫已經在可迭代但通過REST 0元我得到的不支持嵌套查詢錯誤(因爲我沒有映射)。

最後,

春天在什麼-數據ElasticSearch支持通過ES QueryBuilders API嵌套映射?我應該在什麼時候進行映射?

回答

9

彈簧數據elasticsearch現在支持最常見的功能集elasticsearch包括嵌套,內部對象和父子(最近)

詳細的說明可以在managing relationship in elasticsearch找到

嵌套文件實施例

人身份

@Document(indexName = "person" , type = "user") 

    public class Person { 

     @Id 
     private String id; 

     private String name; 

     @Field(type = FieldType.Nested) 
     private List<Car> car; 

     // setters-getters 

    } 

租車實體



    public class Car { 
    private String name; 
    private String model; 
    //setters and getters 
    } 

設置數據



    Person foo = new Person(); 
    foo.setName("Foo"); 
    foo.setId("1"); 

    List cars = new ArrayList(); 
    Car subaru = new Car(); 
    subaru.setName("Subaru"); 
    subaru.setModel("Imprezza"); 
    cars.add(subaru); 
    foo.setCar(cars); 

索引



     IndexQuery indexQuery = new IndexQuery(); 
     indexQuery.setId(foo.getId()); 
     indexQuery.setObject(foo); 

     //creating mapping 
     elasticsearchTemplate.putMapping(Person.class); 
     //indexing document 
     elasticsearchTemplate.index(indexQuery); 
     //refresh 
     elasticsearchTemplate.refresh(Person.class, true); 

搜索



    QueryBuilder builder = nestedQuery("car", boolQuery().must(termQuery("car.name",  "subaru")).must(termQuery("car.model", "imprezza"))); 

    SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); 
    List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class); 

你可以在Nested Object Tests

+0

找到嵌套和內部對象更多的測試用例,你可以請建議使用@Query註釋的方法。 –

+0

你能否建議一種方法來使用spring數據es來關閉_source? – Sachin

+0

SearchQuery searchQuery = new NativeSearchQueryBuilder()。withFields()方法,如果您只想要特定字段。 –