linqu
linqu

Reputation: 11970

minimum_should_match in connection with dis-max-query

I am a neewby in elasticsearch as I just recently switched from Solr. I am now trying to convert an edismax query from my solrconfig to work with elasticsearch.

Basically I want the terms to be searched in two fields at once, so I ended up with this query:

{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "field_1": {
              "query": "term1"
            }
          }
        },
        {
          "match": {
            "field_2": {
              "query": "term1"
            }
          }
        }
      ]
    }
  }
}

This works fine with a single term. In case of multiple terms it's not required that each term is found. However, I could not find a way to implement this feature. That's what the minimum_should_match parameter should be for – which is provided by the bool query.

Let's say I have three terms and I want at least two of them to be found. Via trial and error I checked a lot of variants including something like this:

{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "field_1": {
              "query": "term1 term2 nonexistingterm",
              "operator": "and",
              "minimum_should_match": 2
            }
          }
        },
        {
          "match": {
            "field_2": {
              "query": "term1 term2 nonexistingterm",
              "operator": "and",
              "minimum_should_match": 2
            }
          }
        }
      ]
    }
  }
}

But minimum_should_match does not work here, and due to the and operator no results are found. It doesn't work with or neither as only one hit is enough to return results.

Can someone help me to combine dis_max with minimum should match?

I could not find any documentation about this, so any hints where I can find these information in elasticsearch myself are very appreciated!

Upvotes: 2

Views: 1527

Answers (1)

femtoRgon
femtoRgon

Reputation: 33341

You are using operator: and and providing a minimum_should_match as well, which doesn't make complete sense. With operator: and there, it's producing a query like:

field1:term1 AND field1:term2 AND field1:nonexistingterm

So all of them are required, regardless of what your minimum_should_match is set to. To make effective use of minimum should match behavior, you will need to generate should clauses, with the "or" operator. This is as simple as removing the operator setting, since "or" is the default, and you should see the behavior you are looking for. That is:

{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "field_1": {
              "query": "term1 term2 nonexistingterm",
              "minimum_should_match": 2
            }
          }
        },
        {
          "match": {
            "field_2": {
              "query": "term1 term2 nonexistingterm",
              "minimum_should_match": 2
            }
          }
        }
      ]
    }
  }
}

Upvotes: 2

Related Questions