2013-09-16 148 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()方法,如果您只想要特定字段。 –