简体   繁体   中英

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?

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" : "test@gmail.com",
      "info" :  "java developer"
    },
    {
      "email" : "demo@wikipedia.org",
      "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
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM