Elasticsearch Multi Match Query – Basic

In previous post, we had known some different types of queries. This tutorial shows some simple ways to use Multi Match Query and several types of them.

Related Posts:
Elasticsearch Overview
ElasticSearch – Structure of a Search Request/Response
ElasticSearch Filter vs Query
ElasticSearch Full Text Queries – Basic

More Practice: Elasticsearch Multi Match Query – More Practice

1. Multi Match Query

multi_match query allows us to search for a value across multiple fields.
For example, we want to search for a string across both “title” and “tags”:

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match" : {
      "query":    "restapi",
      "fields": [ "title", "tags"]
    }
  }
}

Response:

{
  ...
  "hits": {
    "total": 2,
    "max_score": 0.58279467,
    "hits": [
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "7",
        "_score": 0.58279467,
        "_source": {
          "title": "How to use Spring Integration Http Inbound with Spring Boot",
          ...
          "tags": [
            "http inbound",
            "inbound adapter",
            "inbound gateway",
            "restapi",
            "springboot",
            "spring integration"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "5",
        "_score": 0.25811607,
        "_source": {
          "title": "How to integrate Angular 4 with SpringBoot RestApi",
          ...
          "tags": [
            "springboot",
            "integration",
            "restapi"
          ]
        }
      }
    ]
  }
}
2. Boosting

– With wildcards:

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match" : {
      "query":    "integration",
      "fields": [ "t*"]
    }
  }
}

– Individual fields: using caret (^) notation

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match" : {
      "query":    "restapi",
      "fields": [ "title^3", "tags"]
    }
  }
}

Now, we can see that _score has changed:

{
  ...
  "hits": {
    "total": 2,
    "max_score": 0.7743482,
    "hits": [
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "5",
        "_score": 0.7743482,
        "_source": {
          "title": "How to integrate Angular 4 with SpringBoot RestApi",
          ...
          "tags": [
            "springboot",
            "integration",
            "restapi"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "7",
        "_score": 0.58279467,
        "_source": {
          "title": "How to use Spring Integration Http Inbound with Spring Boot",
          ...
          "tags": [
            "http inbound",
            "inbound adapter",
            "inbound gateway",
            "restapi",
            "springboot",
            "spring integration"
          ]
        }
      }
    ]
  }
}
3. Types of Multi Match query
3.1 Best Fields

best_fields is default type parameter. It uses the _score from the best field.

This type is most useful when we search for multiple words best found in the same field.
For example, “spring integration” in “title” field is more meaningful than in “tags” field, or “spring” in one field and “integration” in the other:

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match": {
      "query": "spring integration",
      "type": "best_fields",
      "fields": [ "title", "tags" ]
    }
  }
}

The response:

{
  ...
  "hits": {
    "total": 3,
    "max_score": 1.4260926,
    "hits": [
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "7",
        "_score": 1.4260926,
        "_source": {
          "title": "How to use Spring Integration Http Inbound with Spring Boot",
          ...
          "tags": [
            "http inbound",
            "inbound adapter",
            "inbound gateway",
            "restapi",
            "springboot",
            "spring integration"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "6",
        "_score": 1.0836804,
        "_source": {
          "title": "How to upload MultipartFile with Spring Boot",
          ...
          "tags": [
            "springboot",
            "integration"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "5",
        "_score": 0.25316024,
        "_source": {
          "title": "How to integrate Angular 4 with SpringBoot RestApi",
          ...
          "tags": [
            "springboot",
            "integration",
            "restapi"
          ]
        }
      }
    ]
  }
}

If we add a tie_breaker, then it calculates the _score:

score [best matching field] + tie_breaker * score [for all other matching fields]

By default, tie_breaker value is 0.
Now we set tie_breaker:

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match": {
      "query": "spring integration",
      "type": "best_fields",
      "fields": [ "title", "tags" ],
      "tie_breaker": 0.5
    }
  }
}

The response has changed:

{
  ...
  "hits": {
    "total": 3,
    "max_score": 2.0088873,
    "hits": [
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "7",
        "_score": 2.0088873,
        "_source": {
          "title": "How to use Spring Integration Http Inbound with Spring Boot",
          ...
          "tags": [
            "http inbound",
            "inbound adapter",
            "inbound gateway",
            "restapi",
            "springboot",
            "spring integration"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "6",
        "_score": 1.5395588,
        "_source": {
          "title": "How to upload MultipartFile with Spring Boot",
          ...
          "tags": [
            "springboot",
            "integration"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "5",
        "_score": 0.25316024,
        "_source": {
          "title": "How to integrate Angular 4 with SpringBoot RestApi",
          ...
          "tags": [
            "springboot",
            "integration",
            "restapi"
          ]
        }
      }
    ]
  }
}

The _score for document with _id = 5 didn’t change (0.25316024).

3.2 Most Fields

most_fields type is most useful when querying multiple fields that contain the same text analyzed in different ways.

By combining scores from all these fields we can match as many documents as possible with the main field, but use the second and third fields to push the most similar results to the top of the list.

For example:

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match": {
      "query": "reactive publisher",
      "type": "most_fields",
      "fields": [ "title", "tags", "description"]
    }
  }
}

Response:

{
  ...
  "hits": {
    "total": 4,
    "max_score": 2.356826,
    "hits": [
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "9",
        "_score": 2.356826,
        "_source": {
          "title": "Java 9 FLow SubmissionPublisher – A Concrete Publisher",
          "description": "JDK 9 provides a concrete Publisher named SubmissionPublisher that acts as a compliant Reactive Streams Publisher relying on drop handling and/or blocking for flow control. In this tutorial, we’re gonna take a look at SubmissionPublisher and an example that generates items for Subscribers.",
          ...
          "tags": [
            "java 9",
            "flow",
            "reactive programming",
            "reactive streams",
            "publisher"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "10",
        "_score": 2.2391374,
        "_source": {
          "title": "Java 9 Flow API example – Publisher and Subscriber",
          "description": "In previous post, we have general knowledge about Reactive Streams and Java 9 Flow API Components and Behaviour. In this tutorial, we’re gonna look at an example that implements Publisher and Subscriber for reactive programming.",
          ...
          "tags": [
            "java 9",
            "flow",
            "reactive programming",
            "reactive streams",
            "publisher",
            "subscriber"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "11",
        "_score": 2.0980291,
        "_source": {
          "title": "Java 9 Flow API example – Processor",
          "description": "In previous post, we have general knowledge about Reactive Streams and Java 9 Flow API Components and Behaviour. In this tutorial, we’re gonna look at an example that implements Publisher, Subscriber with Processor as a bridge for reactive programming.",
          ...
          "tags": [
            "java 9",
            "flow",
            "reactive programming",
            "reactive streams",
            "publisher",
            "subscriber",
            "processor"
          ]
        }
      },
      {
        "_index": "javasampleapproach",
        "_type": "tutorial",
        "_id": "8",
        "_score": 1.8785784,
        "_source": {
          "title": "Java 9 Flow API – Reactive Streams",
          "description": "Java 9 introduces Reactive Streams under java.util.concurrent.Flow that supports an interoperable publish-subscribe framework. In the tutorial, we’re gonna look at a general view of Reactive Streams and how it comes to Java 9 with some new Flow API Components.",
          ...
          "tags": [
            "java 9",
            "flow",
            "reactive programming",
            "reactive streams"
          ]
        }
      }
    ]
  }
}
3.3 Phrase

phrase and phrase_prefix types behave like best_fields, but they use a match_phrase or match_phrase_prefix query instead of a match query:

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match": {
      "query": "reactive",
      "type": "phrase",
      "fields": [ "title", "tags", "description"]
    }
  }
}

GET javasampleapproach/tutorial/_search
{
  "query": {
    "multi_match": {
      "query": "reacti",
      "type": "phrase_prefix",
      "fields": [ "title", "tags", "description"]
    }
  }
}
3.4 Crosss Fields

You can find it at: Elasticsearch Multi Match Query – More Practice

One thought on “Elasticsearch Multi Match Query – Basic”

Leave a Reply

Your email address will not be published. Required fields are marked *