当前位置: 首页 > 知识库问答 >
问题:

具有嵌套字段和映射的Spring数据弹性搜索

昝光临
2023-03-14

我正在使用spring数据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": { ... },
        ...
}

当我试图查询文档时,我遇到了经典的内部文档与嵌套文档的问题,它无法识别嵌套元素。

当我尝试更新映射以使用嵌套文档时,我得到“无法从非嵌套更改为嵌套”。

我是否应该告诉spring data es@NestedField=

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

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

然后使用spring数据存储库进行查询:

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支持嵌套映射?我应该什么时候进行映射?

共有1个答案

段干河
2023-03-14

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

    }

汽车实体



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

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

 类似资料:
  • 我有一个设计糟糕的文档结构: 我想从上面的文档中检索标题、Fach和代码。 多谢了。

  • 我使用的是ES版本5.6。我有一个像下面这样的文档存储在ES中。 我想搜索所有已“启用”的字段。 我尝试了以下查询,但都不起作用。 但是下面的查询起作用了 因此,看起来只匹配顶级字段,而不匹配嵌套字段。是否有任何方法可以查询包含在所有字段中的文本,包括嵌套字段。我不想显式指定嵌套字段名。我正在寻找一种全局搜索,我想在文档中的任何地方搜索“文本”。 谢了。

  • 我试图为一个业务场景制定一个查询,其中我们有一个名为“types”的嵌套字段类型(即类似于字符串的ArrayList)。下面是以“类型”作为字段之一的索引文档示例。 文件1:{“类型”:[{“标签”:“对话”,},{“标签”:“暴力”,},{“标签”:“语言”,}} 文档2:{“类型”:[{“标签”:“对话框”,}} 现在,要求搜索查询最多匹配字段值中的一个值,即如果用户搜索“对话框”,那么它应该

  • 问题内容: 我想将一些JSON保留为看起来像这样的elastic(search): 点是具有弹性的geo_point类型的列表。因为它们是geo_point值,所以我需要定义索引映射,但是我能看到的最接近的方法是: 这意味着让每个点都是具有单个位置键和geo_point值的地图。我只想要geo_points,这可能吗? 问题答案: 您可以如下定义映射:

  • 我正在尝试从索引中获取城市为空的所有记录。 源看起来像: 因此,当我试图只搜索那些城市为空的源代码时,我会收到不同类型的错误。 must\u not exists返回包含非空城市的源。 我尝试了不同类型的脚本来过滤掉数据,但没有结果。 _mapping请求,城市有嵌套类型。 请给出建议

  • 假设我有这些实体: null