【问题标题】:Spring Data Elastic Search with Nested Fields and mapping带有嵌套字段和映射的 Spring Data 弹性搜索
【发布时间】:2023-03-02 21:17:01
【问题描述】:

我正在同时使用 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" into mapping 吗?有没有办法在创建索引和映射时向 spring-data 添加自定义映射?

另外,我正在通过以下方式初始化索引:

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

然后使用 spring-data 存储库查询:

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

这里 res 在 Iterable 中有 0 个元素,但通过 REST 我得到了不支持嵌套查询的错误(因为我在映射中没有它)。

终于,

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

【问题讨论】:

    标签: elasticsearch spring-data spring-data-elasticsearch


    【解决方案1】:

    Spring data 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找到更多关于嵌套和内部对象的测试用例

    【讨论】:

    • 你能推荐一个使用@Query注解的方法吗?
    • 您能否建议一种使用 spring data es 关闭 _source 的方法?
    • SearchQuery searchQuery = new NativeSearchQueryBuilder().withFields() 方法,如果您只需要特定字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2020-06-14
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    相关资源
    最近更新 更多