web-dev-qa-db-ja.com

ネストされたフィールドとマッピングを使用したSpringData Elastic Search

私は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": { ... },
        ...
}

ドキュメントをクエリしようとすると、古典的な内部ドキュメントとネストされたドキュメントの問題が発生し、ネストされた要素が認識されません。

ネストされたドキュメントを使用するようにマッピングを更新しようとすると、「ネストされていないドキュメントからネストされたドキュメントに変更できません」というメッセージが表示されます。

どういうわけか、@ NestedField => type: "nested"をマッピングにspring-data-esに伝える必要がありますか?インデックスとマッピングを作成するときに、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を介したネストされたマッピングをサポートしていますか?そのマッピングをいつ行う必要がありますか?

11
Alexis

Springデータelasticsearchは、ネストされた、内部オブジェクト、親子(最近)など、elasticsearchの一般的な機能セットのほとんどをサポートするようになりました。

詳細な説明は 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

    }
</ code>

車のエンティティ



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

ネストされたオブジェクトと内部オブジェクトに関するその他のテストケースは、 ネストされたオブジェクトのテスト で見つけることができます。

14
Mohsin Husen