首页 > 解决方案 > 如何在spring-data弹性搜索中通过过滤嵌套对象来构建搜索查询?

问题描述

我的文档是这样的:

class Foo{
 private Integer idDl;
 private String Name;
 private String Add;
 @Field(type = FieldType.Nested)
 private List< Bar> Bar;
 }
 
 class Bar{
 private Integer barId;
 private List<String> barData
 }

样本Foo数据如下:

{
    "idDl": 123,
    "Name": "ABCD",
    "Add": "FL",
    "Bar": [
        {
            "barId": 456,
            "barData": [
                "Bar1",
                "Bar2"
            ]
        },
        {
            "barId": 985,
            "barData": [
                "Bar4",
                "Bar5"
            ]
        }
    ]
}

我想返回所有匹配的Foo对象,Bar.barId但与Bar列表对象一样FooFoo必须只包含一个Barid 与用户提供的 id 匹配的对象。我使用NativeSearchQueryBuilderspring-data-elasticsearch 提供的作为:

String[] includeFields = new String[]{"idDl", "Name"};
String[] excludeFields = new String[]{"Add"}; // to exclude Add field of Foo
Query searchQuery = new NativeSearchQueryBuilder()
            .withQuery(matchQuery("Bar.barId", 456))
            //.withQuery(termQuery("Bar.barId", 456))
            .withSourceFilter(new FetchSourceFilter(includeFields, excludeFields))
            .build();
return elasticsearchRestTemplate.queryForList( searchQuery, Foo.class);

我得到的响应由所有Bar对象组成,而与 ID 无关,这是示例响应:

[
    {
        "idDl": 123,
        "Name": "ABCD",
        "Add": "FL",
        "Bar": [
            {
                "barId": 456,
                "barData": [
                    "Bar1",
                    "Bar2"
                ]
            },
            {
                "barId": 985,
                "barData": [
                    "Bar4",
                    "Bar5"
                ]
            }
        ]
    },
    {
        "idDl": 758,
        "Name": "PQR",
        "Add": "NY",
        "Bar": [
            {
                "barId": 456,
                "barData": [
                    "Bar1",
                    "Bar2"
                ]
            },
            {
                "barId": 671,
                "barData": [
                    "Bar24",
                    "Bar25"
                ]
            }
        ]
    }
]

我尝试termQuery按照片段中的评论使用,但我没有得到响应,因为matchQuery我得到了上述响应。在响应中,Bar必须只包含 ID 为 456 的对象,即在查询中发送的 ID。任何建议都会有所帮助

标签: spring-bootspring-mvcelasticsearchspring-dataspring-data-elasticsearch

解决方案


您正在查询Foo存在Bar与条件匹配的对象,并且 Elasticsearch 返回这些Foos。如果您想拥有唯一Bar匹配的 s,则需要将 inner_hits 添加到您的查询中。

检查这个问题和答案以了解如何检索这些,使用 Spring Data Elasticsearch 检索内部命中将随版本 4.1 提供。


推荐阅读