2

Let's say I have an index in ElasticSearch 6:

"mappings" : {
  "pet" : {
      "name" : {
         "type" : "text"
      },          
      "info" : {
         "type" : "text"
      },
      "description" : {
         "type" : "text"
      }
   }
}

I need to perform full-text search by all fields with the same input string that is typed by user: 'big grey dog' or 'small cute cat'. How can I up in relevance search those units, which contain more words from input. No matter where - name or description. I want that unit:

{
    "name" : "big",
    "info" : "grey",
    "description" : "dog" 
}

have higher score then unit:

{
    "name" : "grey dog",
    "info" : "dog dog grey dog",
    "description" : "grey dog grey dog grey dog" 
}
KozhevnikovDmitry
  • 1,660
  • 12
  • 27

1 Answers1

1

If you are using a multiMatch query you should use the cross_field type with AND operator (see here).

But as it will only match document containing all terms you should use a bool query with two should clauses, a loose clause with a default type ( aka best_fields ) and default OR operator and a strict one with type cross_field and operator AND.

With this it will boost documents matching all field, and continue to display with lower score document only matching some terms :

Something like :

"query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "query": "<here your query>",
            "fields": ["name", "info", "description"],
            "type": "cross_fields",
            "operator": "AND"
          }
        },
        {
          "multi_match": {
            "query": "<here your query>",
            "fields": ["name", "info", "description"],
          }
        }
      ]
    }
  }
Pierre Mallet
  • 7,053
  • 2
  • 19
  • 30