Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Elasticsearch nested field multimatch query

I'm using elasticsearch with spring-data-elastic. And try to use multi search. The problem is while search wprking with class fields, its not working with nested fields. My mapping is like below

{
    "archieve": {
        "mappings": {
            "author": {
                "properties": {
                    "books": {
                        "type": "nested",
                        "properties": {
                            "id": {
                                "type": "long"
                            },
                            "name": {
                                "type": "string",
                                "analyzer": "standard"
                            }
                        }
                    },
                    "id": {
                        "type": "long"
                    },
                    "firstName": {
                        "type": "string",
                        "analyzer": "standard"
                    },
                    "lastName": {
                        "type": "string",
                        "analyzer": "standard"
                    }
                }
            }
        }
    }
}

and I have an endpoint with searchQuery like:

  @GetMapping(value = "/es/archieve/multi/{keyword}")
  public Page<Author> getBrandMulti(@PathVariable String keyword, Pageable pageable) {

      SearchQuery searchQuery = new NativeSearchQueryBuilder()
                      .withQuery(QueryBuilders.multiMatchQuery(keyword)
                              .field("firstName", 1.2f)
                              .field("books.name", 1.1f)
                              .type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                              .fuzziness(Fuzziness.TWO)
                      )
                      .withIndices("archieve")
                      .withTypes("author")
                      .withPageable(pageable)
                      .build();

      return elasticsearchTemplate.queryForPage(searchQuery, Author.class);
  }

The problem is query is not working for nested field. Is there any suggestion, regards?

Update

In fact nested objects can be queried as

NativeSearchQueryBuilder()
    .withQuery(QueryBuilders.nestedQuery("books", 
         QueryBuilders.termQuery("books.name", searchKey)))

Is there anyway to concat two queries like

NativeSearchQueryBuilder()
    .withQuery(Query1)
    .withQuery(Query1)
    .build();
like image 486
ozhanli Avatar asked Aug 30 '25 18:08

ozhanli


1 Answers

ES Nested Objects

As the document says, when you query a nested field, you have to use nested query:

Because nested objects are indexed as separate hidden documents, we can’t query them directly. Instead, we have to use the nested query to access them:

Spring Data

Back to the spring data, I prefer the way using Query, which IMO, more readable:

@Query(" {" +
        " \"bool\": {\n" +
        "     \"should\": [\n" +
        "       {\n" +
        "         \"multi_match\": {\n" +
        "           \"query\": \"?0\",\n" +
        "           \"fields\": [\"firstName\"]\n" +
        "         }\n" +
        "       },\n" +
        "       {\n" +
        "         \"nested\": {\n" +
        "           \"path\": \"books\",\n" +
        "           \"query\": {\n" +
        "             \"match\": {\n" +
        "               \"books.name\": \"?0\"\n" +
        "             }}\n" +
        "         }\n" +
        "       } ]\n" +
        "  }" +
        "}")
Page<EsBrand> findByNameOrBooks(String info, Pageable pageable);

You can put this signature in your repo interface, which spring will implement a proxy to do the other jobs.

like image 177
Tony Avatar answered Sep 02 '25 11:09

Tony