3
votes

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

1 Answers

2
votes

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.