使用嵌套字段和映射的Spring数据弹性搜索 [英] Spring Data Elastic Search with Nested Fields and mapping

查看:393
本文介绍了使用嵌套字段和映射的Spring数据弹性搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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 = analyze,store = true)
private String field1;

// ...更多字段。

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

// ... getter和setter
}

  class B {// some normal pojo} 

当我让spring-data做映射时,我得到:

  a:{
properties:{
bs:{
properties:{
someBProperty:{
type字符串
},
BId:{
type:string
}
}
},
id :{...},
...
}

我试图查询文档,我得到了古典的内在和嵌套文件的问题,它不能识别嵌套的元素。



当我尝试更新映射使用嵌套文件我得到不能从非嵌套到嵌套。



我应该告诉spring-data-es不知何故@NestedFi eld => type:嵌套成映射?有没有办法添加自定义映射到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()。必须(QueryBuilders.matchQuery(as.field1,A1))。必须(QueryBuilders .matchQuery(as.field2,B1)));

可替代<非规范化关系文档> res = aRepository.search(builder);

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



终于,



Spring-Data- ElasticSearch通过ES QueryBuilders API支持嵌套映射?什么时候应该做映射?

解决方案

Spring数据弹性搜索现在支持大部分弹性搜索的常用功能集,包括嵌套,内部对象和父母子女(最近)



详细的说明可以在在弹性搜索中管理关系



嵌套文档示例



个人实体



  

  @Document(indexName =person,type =user)

public class Person {

@Id
private String id ;

private String name;

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

// setters-getters

}



汽车实体

  

public class Car {
private String name;
私人字符串模型;
// setters和getters
}

设置数据

  

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

列表cars = new ArrayList();
汽车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);

//创建映射
elasticsearchTemplate.putMapping(Person.class);
//索引文档
elasticsearchTemplate.index(indexQuery);
// refresh
elasticsearchTemplate.refresh(Person.class,true);

搜索

  

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

SearchQuery searchQuery = new NativeSearchQueryBuilder()。withQuery(builder).build();
列出people = elasticsearchTemplate.queryForList(searchQuery,Person.class);

您可以在嵌套对象测试


I am using spring-data-elasticsearch and elasticsearch together to query documents. I'd like to do nested queries on nested documents.

I have this in 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
}

And

class B { // some normal pojo }

When I let spring-data do the mapping, I get :

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

When I am trying to query the document, I get the classical inner vs nested documents problems and it doesn't recognize the nested element.

When I try to update mapping to use nested document I get "can't be changed from non-nested to nested".

Should I tell spring-data-es somehow that @NestedField => type: "nested" into mapping ? Is there a way to add custom mapping to spring-data when it create index & mapping ?

Also, I am initializing indexes via :

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

And then querying using 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);

Here the res has 0 element in the Iterable but via REST I get the error on the nested query not supported (as I don't have it in mapping).

finally,

Does Spring-Data-ElasticSearch supports nested mappings via ES QueryBuilders API ? When should I make that mapping happens ?

解决方案

Spring data elasticsearch now supports most of the common feature set of elasticsearch including Nested, Inner Objects and Parent Child(recently)

Detailed explanation can be found at managing relationship in elasticsearch

Nested document Example

Person Entity

   @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

    }

Car Entity



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

Setting Up Data



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

Indexing



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

Searching

 

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

you can find more test cases about Nested and Inner Object at Nested Object Tests

这篇关于使用嵌套字段和映射的Spring数据弹性搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆