Spring Data Elastic Search与嵌套字段和映射

15

我正在使用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-data进行映射时,我得到:

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

当我尝试查询文档时,出现了内部文档和嵌套文档的经典问题,并且它无法识别嵌套元素。

当我尝试更新映射以使用嵌套文档时,会出现“无法从非嵌套更改为嵌套”的错误。

我应该如何告诉spring-data-es将@NestedField => type: "nested"添加到映射中?在spring-data创建索引和映射时,有没有添加自定义映射的方法?

此外,我是通过以下方式初始化索引的:

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

然后使用Spring Data Repository进行查询:

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);

在这里,Iterable中的res没有元素,但是通过REST获取嵌套查询不受支持的错误(因为它不在映射中)。

最后,

Spring-Data-Elasticsearch是否支持通过ES QueryBuilders API进行嵌套映射?我应该在什么时候进行映射?

1个回答

18

Spring data elasticsearch现在支持Elasticsearch的大多数常见功能集,包括Nested、Inner Objects和Parent Child(recently)

详细说明可在managing relationship in elasticsearch找到

嵌套文档示例

人员实体

(原内容中的html标签未闭合,我这里默认为其正确闭合)
   @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);

您可以在嵌套对象测试中找到更多关于嵌套和内部对象的测试用例。


请问您能否建议一种使用@Query注释的方法来实现相同的功能。 - Munees Majid
请问您能否建议一种使用Spring Data ES关闭_source的方法? - Sachin
SearchQuery searchQuery = new NativeSearchQueryBuilder().withFields() 方法可以让你只获取特定的字段。 - Mohsin Husen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接