How to create multimatch query in elasticsearch using JAVA API

Viewed 2867

I am trying to create elastic search query using JAVA api but it is adding some extra elements in JSON and also the fields are appending with ^1.0.

Expected JSON QUERY:

{
      "from": 0,
      "query": {
        "bool": {
          "should": [
            {
              "multi_match": {
                "fields": [
                  "column1",
                  "column2",
                  "column3",
                  "column4"
                ],
                "minimum_should_match": 2,
                "query": "test",
                "type": "phrase",
                "boost": 5
              }
            },
            {
              "multi_match": {
                "fields": [
                  "column1",
                  "column2",
                  "column3",
                  "column4"
                ],
                "query": "test",
                "type": "phrase",
                "boost": 5
              }
            },
            {
              "multi_match": {
                "fields": [
                  "column1",
                  "column2",
                  "column3",
                  "column4"
                ],
                "operator": "and",
                "query": "test",
                "type": "cross_fields"
              }
            },
            {
              "multi_match": {
                "fields": [
                  "column1",
                  "column2",
                  "column3",
                  "column4"
                ],
                "operator": "or",
                "query": "test",
                "type": "cross_fields"
              }
            },
            {
              "multi_match": {
                "fields": [
                  "column1",
                  "column2",
                  "column3",
                  "column4"
                ],
                "fuzziness": "AUTO",
                "query": "test",
                "type": "best_fields"
              }
            }
          ]
        }
      },
      "size": 250,
      "sort": [
        {
          "_score": {
            "order": "desc"
          }
        }
      ]
    }

output from code :

{
  "bool" : {
    "should" : [
      {
        "multi_match" : {
          "query" : "test",
          "fields" : [
            "column1^1.0",
            "column2^1.0",
            "column3^1.0",
            "column4^1.0"
          ],
          "type" : "phrase",
          "operator" : "OR",
          "slop" : 0,
          "prefix_length" : 0,
          "max_expansions" : 50,
          "minimum_should_match" : "2",
          "zero_terms_query" : "NONE",
          "auto_generate_synonyms_phrase_query" : true,
          "fuzzy_transpositions" : true,
          "boost" : 5.0
        }
      },
      {
        "multi_match" : {
          "query" : "test",
          "fields" : [
            "column1^1.0",
            "column2^1.0",
            "column3^1.0",
            "column4^1.0"
          ],
          "type" : "phrase",
          "operator" : "OR",
          "slop" : 0,
          "prefix_length" : 0,
          "max_expansions" : 50,
          "zero_terms_query" : "NONE",
          "auto_generate_synonyms_phrase_query" : true,
          "fuzzy_transpositions" : true,
          "boost" : 5.0
        }
      },
      {
        "multi_match" : {
          "query" : "test",
          "fields" : [
            "column1^1.0",
            "column2^1.0",
            "column3^1.0",
            "column4^1.0"
          ],
          "type" : "cross_fields",
          "operator" : "AND",
          "slop" : 0,
          "prefix_length" : 0,
          "max_expansions" : 50,
          "zero_terms_query" : "NONE",
          "auto_generate_synonyms_phrase_query" : true,
          "fuzzy_transpositions" : true,
          "boost" : 1.0
        }
      },
      {
        "multi_match" : {
          "query" : "test",
          "fields" : [
            "column1^1.0",
            "column2^1.0",
            "column3^1.0",
            "column4^1.0"
          ],
          "type" : "cross_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
        }
      },
      {
        "multi_match" : {
          "query" : "test",
          "fields" : [
            "column1^1.0",
            "column2^1.0",
            "column3^1.0",
            "column4^1.0"
          ],
          "type" : "best_fields",
          "operator" : "OR",
          "slop" : 0,
          "fuzziness" : "AUTO",
          "prefix_length" : 0,
          "max_expansions" : 50,
          "zero_terms_query" : "NONE",
          "auto_generate_synonyms_phrase_query" : true,
          "fuzzy_transpositions" : true,
          "boost" : 1.0
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

JAVA code which I am using is:

        String queryString = "test";
        QueryBuilder cluase0 = QueryBuilders.multiMatchQuery(queryString, 
                "column1",
                  "column2",
                  "column3",
                  "column4").type(Type.PHRASE).boost(5f).minimumShouldMatch("2");


        QueryBuilder clause1 = QueryBuilders.multiMatchQuery(queryString, 
                "column1",
                  "column2",
                  "column3",
                  "column4").type("phrase").boost(5);







        QueryBuilder clause2 = QueryBuilders.multiMatchQuery(queryString, 
                "column1",
                  "column2",
                  "column3",
                  "column4").operator(Operator.AND).type("cross_fields");



        QueryBuilder clause3 = QueryBuilders.multiMatchQuery(queryString, 
                "column1",
                  "column2",
                  "column3",
                  "column4").operator(Operator.OR).type("cross_fields");



        QueryBuilder clause4 = QueryBuilders.multiMatchQuery(queryString, 
                "column1",
                  "column2",
                  "column3",
                  "column4").fuzziness("AUTO").type("best_fields");





        QueryBuilder combinedBoolQuery = QueryBuilders.boolQuery()
                .should(cluase0).should(clause1).should(clause2).should(clause3).should(clause4);
        System.out.println(combinedBoolQuery);

I am not getting what is getting wrong, How I can get the required JSON query by modifyig the Java code.

1 Answers

You are almost correct, only few changes will make it work.

SearchRequest searchRequest = new SearchRequest("index-name");
String queryString = "test";
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// Multimatch query builder 1
MultiMatchQueryBuilder multiMatchQueryBuilder1 = new MultiMatchQueryBuilder(queryString, "firstName", "lastName",
      "password", "emailId", "userId", "mobileNumber");
multiMatchQueryBuilder1.operator(Operator.AND);
searchSourceBuilder.query(multiMatchQueryBuilder1);

// Multimatch query builder 2
MultiMatchQueryBuilder multiMatchQueryBuilder2 = new MultiMatchQueryBuilder(queryString, "firstName", "lastName",
      "password", "emailId", "userId", "mobileNumber");
multiMatchQueryBuilder1.operator(Operator.OR);
searchSourceBuilder.query(multiMatchQueryBuilder2);

// Multimatch query builder 3
MultiMatchQueryBuilder multiMatchQueryBuilder3 = new MultiMatchQueryBuilder(queryString, "firstName", "lastName",
      "password", "emailId", "userId", "mobileNumber").type("cross_fields");
multiMatchQueryBuilder1.operator(Operator.OR);
searchSourceBuilder.query(multiMatchQueryBuilder3);

// Multimatch query builder 4
MultiMatchQueryBuilder multiMatchQueryBuilder4 = new MultiMatchQueryBuilder(queryString, "firstName", "lastName",
      "password", "emailId", "userId", "mobileNumber").fuzziness("AUTO").type("best_fields");
multiMatchQueryBuilder1.operator(Operator.OR);
searchSourceBuilder.query(multiMatchQueryBuilder4);

searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = esclient.search(searchRequest, RequestOptions.DEFAULT);
  1. You need to use the SearchSourceBuilder and add your individual querybuilder like multiMatchQueryBuilder1, multiMatchQueryBuilder2 ,multiMatchQueryBuilder3 to it, using searchSourceBuilder.query(multiMatchQueryBuilder2).
  2. You also need to add SearchSourceBuilder to SearchRequest object using searchRequest.source(searchSourceBuilder) method.
  3. ES by default boost every field by a factor of 1, hence you are seeing ^1 with every field in generated ES JSON query, please refer boost in ES for more info.
Related