1

My Document is like:

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

and Foo sample response data is like:

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

I want to return all Fooobjects where Bar.barId is matching. I am using NativeSearchQueryBuilder provided by spring-data-elasticsearch as:

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

We have also tried using nestedQuery as follows:

 SearchQuery  searchQuery = new NativeSearchQueryBuilder()
                .withQuery(nestedQuery("Bar",
                 boolQuery().must(termQuery("Bar.barId", "A456B")), ScoreMode.Max))
                .withIndices(indices)
                .withSourceFilter(new FetchSourceFilter(includeFields, excludeFields))
                .build();
         return elasticsearchRestTemplate.queryForList(searchQuery, Foo.class);

But getting exception as:

org.elasticsearch.ElasticsearchStatusException: Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]
    at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177) ~[elasticsearch-6.8.7.jar:6.8.7]
    at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:2053) ~[elasticsearch-rest-high-level-client-6.8.7.jar:6.8.7]
    at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:2030) ~[elasticsearch-rest-high-level-client-6.8.7.jar:6.8.7]
    at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1777) ~[elasticsearch-rest-high-level-client-6.8.7.jar:6.8.7]
    at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1734) ~[elasticsearch-rest-high-level-client-6.8.7.jar:6.8.7]
    at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1696) ~[elasticsearch-rest-high-level-client-6.8.7.jar:6.8.7]
    at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:1092) ~[elasticsearch-rest-high-level-client-6.8.7.jar:6.8.7]

I am using termQuery as in the first snippet but i ain't getting response for it and but instead if i use matchQuery("Bar.barId", "A456B") I am getting the response. We just want to check query performance using termQuery and matchQuery.How to fetch the data using termQuery ?

P.S: we are using spring-boot-starter-data-elasticsearch 2.2.6.RELEASE in our spring-boot project.

6
  • Check whether cluster is up? Commented Jul 17, 2020 at 16:27
  • 1
    @gibbs, It's up. We're getting results for other match queries. Commented Jul 17, 2020 at 19:30
  • What is the mapping of Bar.barid? Commented Jul 18, 2020 at 5:41
  • it is of type text Commented Jul 18, 2020 at 5:46
  • What is the analyser used on that? Commented Jul 18, 2020 at 5:51

2 Answers 2

1

You haven't specified any analyser. So default one is used standard analyzer

Unlike full-text queries, term-level queries do not analyze search terms. Instead, term-level queries match the exact terms stored in a field.

Reference

Term query do not analyse which means it looks for A456B but index contains a456b due to the behaviour of standard analyzer which contains lowercase tokenizer

Whereas match query is a full text search query which does the analyser on index time and search time. So search time a456bmatches the words in the indexa3456b`.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks @Gibbs. Would you please suggest how to make this term query work? we just wanted to check the performance of term vs match queries. Any suggestions will be really helpful.
Give a try on Bar.barId.keyword in terms query
Can you add your mapping by executing http://host:port/indexName/_mapping
that's what we did at the start.
we have already added mapping by hitting the service you mentioned
|
1

We have the similar requirements and solved using this snippet, I've tried to covert it, according to your requirement. Code is pretty straight forward, let me know if you need further clarification.

    BoolQueryBuilder boolQueryBuilder = boolQuery();
    BoolQueryBuilder nestedBoolQueryBuilder = boolQuery().must(boolQuery()
                    .should(termQuery("Bar.barId", barId.toLowerCase()))).minimumNumberShouldMatch(1);
    QueryBuilder nestedQueryBuilder = nestedQuery("Bar", nestedBoolQueryBuilder);
    boolQueryBuilder = boolQueryBuilder.must(nestedQueryBuilder);
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(boolQueryBuilder)
            .withPageable(pageable)
            .build();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.