Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elasticsearch match all query using Java API

We are using Elasticsearch version 7.3.1 and Java API.

We are implementing a "free search", which means a search for a value in ALL the fields in each segment in Elasticsearch. If that value appears in at least one of the segment's fields, it should be returned.

Until now, we have used the following: QueryBuilders.multiMatchQuery(value) and it worked well.

As for today, we have added to the mapping file some nested (Elasticsearch data type) type fields.

After that change, the code above does not return the expected results anymore.

How can I implement a search in ALL the fields in a segment without specifying each field to search?

like image 457
Roy Leibovitz Avatar asked Apr 11 '26 21:04

Roy Leibovitz


1 Answers

You could implement the logic of _all of previous elasticsearch versions (this was removed after version 6 I believe).

PUT stackoverflow
{
  "mappings": {
    "properties": {
      "all": {
        "type": "text"
      },
      "group": {
        "type": "text",
        "copy_to": "all"
      },
      "user": {
        "type": "nested",
        "properties": {
          "email": {
            "type": "keyword",
            "copy_to": "all"
          },
          "info": {
            "type": "text",
            "copy_to": "all"
          }
        }
      }
    }
  }
}

Basically you add the copy_to parameter.

PUT stackoverflow/_doc/1
{
  "group" : "programmers",
  "user" : [
    {
      "email" : "[email protected]",
      "info" :  "java developer"
    },
    {
      "email" : "[email protected]",
      "info" :  "css guru"
    }
  ]
}

Then you can search against the all field

GET stackoverflow/_search
{
  "query": {
    "match": {
      "all": "guru"
    }
  }
}

Update

Here is an example of how to modify your query in order for it to work without copy_to

GET stackoverflow/_search
{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
        {
          "multi_match": {
            "query": "SEARCH_INPUT_HERE",
            "fields": [
              "group"
            ]
          }
        },
        {
          "nested": {
            "path": "user",
            "query": {
              "multi_match": {
                "query": "SEARCH_INPUT_HERE",
                "fields": [
                  "user.email", "user.info"
                ]
              }
            }
          }
        }
      ]
    }
  }
}

Update 2

public static void main(String[] args) {
    String queryInput = "QUERY_INPUT_HERE";
    String[] nested = {"user", "product"};

    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(queryInput, "*");

    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    List<QueryBuilder> shouldQueryBuilders = boolQueryBuilder.should();

    shouldQueryBuilders.add(multiMatchQueryBuilder);
    for(String path : nested) {
        NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(path, multiMatchQueryBuilder, ScoreMode.Avg);
        shouldQueryBuilders.add(nestedQueryBuilder);
    }

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(boolQueryBuilder);

    SearchRequest searchRequest = new SearchRequest();
    searchRequest.source(searchSourceBuilder);
    searchRequest.indices("MY_INDEX");

    System.out.println(searchRequest.toString());
}

Output

{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "query": "QUERY_INPUT_HERE",
            "fields": [
              "*^1.0"
            ],
            "type": "best_fields",
            "operator": "OR",
            "slop": 0,
            "prefix_length": 0,
            "max_expansions": 50,
            "zero_terms_query": "NONE",
            "auto_generate_synonyms_phrase_query": true,
            "fuzzy_transpositions": true,
            "boost": 1.0
          }
        },
        {
          "nested": {
            "query": {
              "multi_match": {
                "query": "QUERY_INPUT_HERE",
                "fields": [
                  "*^1.0"
                ],
                "type": "best_fields",
                "operator": "OR",
                "slop": 0,
                "prefix_length": 0,
                "max_expansions": 50,
                "zero_terms_query": "NONE",
                "auto_generate_synonyms_phrase_query": true,
                "fuzzy_transpositions": true,
                "boost": 1.0
              }
            },
            "path": "user",
            "ignore_unmapped": false,
            "score_mode": "avg",
            "boost": 1.0
          }
        },
        {
          "nested": {
            "query": {
              "multi_match": {
                "query": "QUERY_INPUT_HERE",
                "fields": [
                  "*^1.0"
                ],
                "type": "best_fields",
                "operator": "OR",
                "slop": 0,
                "prefix_length": 0,
                "max_expansions": 50,
                "zero_terms_query": "NONE",
                "auto_generate_synonyms_phrase_query": true,
                "fuzzy_transpositions": true,
                "boost": 1.0
              }
            },
            "path": "product",
            "ignore_unmapped": false,
            "score_mode": "avg",
            "boost": 1.0
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1.0
    }
  }
}
like image 199
Alkis Kalogeris Avatar answered Apr 13 '26 12:04

Alkis Kalogeris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!