如何在 spring-data 弹性搜索中构建带有嵌套对象过滤的搜索查询?

How to build a search query with filtering for nested objects in spring-data elastic search?

我的文档是这样的:

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"
            ]
        }
    ]
}

我想 return 所有 Foo 匹配 Bar.barId 的对象,但因为 BarFoo 中的列表对象,Foo只能包含一个 Bar 对象,其 ID 与 user.I 提供的 ID 匹配,我使用 spring-data-elasticsearch 提供的 NativeSearchQueryBuilder 作为:

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。任何建议都会有所帮助

您正在查询 Foo 个对象,其中存在符合条件的 Bar 和 Elasticsearch returns 这些 Foo。如果您只想获得匹配的 Bar,则需要将 inner_hits 添加到您的查询中。

检查 this question 并回答如何检索这些内容,使用 Spring 检索内部命中数据 Elasticsearch 将随版本 4.1 一起提供。