Query rules play an important role in search applications to tune search relevancy where we want to configure search results as per our business needs. For example, promote iphone at top when user searched for mobile phones or boost the score for documents containing iphone by boost factor, so they can be ranked in top results.

Deploy this pipeline with one-click

Demo

Pre Setup

Let's define the basics of the pipeline. It will be in the following way:

Copy
enabled: true
description: Promote cell phones

routes:
  - path: /query-boost-example
    method: POST
    classify:
      category: reactivesearch

envs:
    category: reactivesearch
    index: [best-buy-dataset]

We have defined the search route details along with some envs variables to configure the route category and search index. We would be using the best-buy-dataset index, you can browse the data at here.

Stages

Now that we have the pre setup out of the way, let's define the stages for the pipeline.

Authorization

We need to make sure that the requests made to this endpoint are authenticated. To do this, we can use the pre-built stage authorization. We can define it in the following way:

Copy
- id: authorization
  use: authorization
  continueOnError: false

It's as simple as that, we don't need to do anything else, the rest will be taken care of by the pipeline.

Apply Facet

The following stage defines a facet to filter search results by department value as DIGITAL COMMUNICATIO.

Copy
- id: addFilter
  use: addFilter
  continueOnError: false
  description: Filter results by department
  inputs:
    data: mongodb
      department.keyword: DIGITAL COMMUNICATIO   

Replace Words

The following stage replaces the iphone word in search query to iphone 11 apple so we can get more specific results for latest iphone series available in stock.

Copy
- id: replaceWords
  use: replaceWords
  continueOnError: false
  description: Replaces iphone word to iphone 11 apple
  inputs:
    data:
      iphone: iphone 11 apple   

Boost Results by Score

In the following stage, we are boosting the documents for which categoryPath.name field is cell Phones or Prepaid Phones.

Copy
- id: boostByScore
  use: boost
  continueOnError: false
  inputs:
    dataField: categoryPath.name
    value: [cell Phones, Prepaid Phones] 
    boostType: score
    boostFactor: 0
    boostOp: 'add'

Above stage will translate to the following ElasticSearch query:

Copy
{
  "query": {
    <query from search value...>
    "match": {
      "categoryPath.name": {
        "query": "cell Phones Prepaid Phones",
        "operator": "or" 
      }
    }
  }
}

Other types of boosting

boost stage also supports geo and range based query boosting. Following is an example on how range based query boosting works:

Copy
- id: boostByScore
  use: boost
  continueOnError: false
  inputs:
    dataField: categoryPath.name
    value:
      start: 23
      end: 45
    boostType: score
    boostFactor: 0
    boostOp: 'add'

Above stage translates to the following ElasticSearch query:

Copy
{
  "query": {
    <query from search value...>
    "range": {
      "categoryPath.name": {
        "gte": 23,
        "lte": 45
      }
    }
  }
}

Following is an example of boosting on a geo location field. Note that in order to boost on a geo field, the field type should be a supported location field.

Copy
- id: boostByScore
  use: boost
  continueOnError: false
  inputs:
    dataField: location
    value:
      location: "22.3184816, 73.17065699999999"
      unit: mi
      distance: 45
    boostType: score
    boostFactor: 0
    boostOp: 'add'

Above stage translates to the following ElasticSearch query:

Copy
{
  "query": {
    <query from search value...>
    "geo_distance": {
      "distance": "45mi",
      "location": "22.3184816, 73.17065699999999"
    }
  }
}

Boost Results at Top (Promote Results)

The following stage would promote the documents at the top for which albumTitle field contains Galaxy Note10+. Since we want to promote maximum one document, so we have set the boostMaxDocs to 1.

Copy
- id: promoteResults
  use: boost
  continueOnError: false
  inputs:
    dataField: albumTitle
    value: [Galaxy Note10+]
    boostType: promote
    boostMaxDocs: 1

ReactiveSearch Query

We will use the pre-built stage reactivesearchQuery for this stage. We will be converting the RS Query to ES Query in this stage.

We can define this stage in the following way:

Copy
- use: reactivesearchQuery
  continueOnError: false

Elastic Search Query

In the final stage, we make the ES call and return the response accordingly. At this stage, the request body should be converted to the ES body so that ES can understand it.

We will be using the pre-built stage elasticsearchQuery at this stage.

We can define this stage in the following way:

Copy
- use: elasticsearchQuery
  continueOnError: false

Complete Pipeline

Now that all the stages are defined, let's take a look at the whole pipeline at once:

Copy
enabled: true
description: Promote cell phones

routes:
  - path: /query-boost-example
    method: POST
    classify:
      category: reactivesearch

envs:
    category: reactivesearch
    index: [best-buy-dataset]

stages:
- id: authorization
  use: authorization
  continueOnError: false
- id: addFilter
  use: addFilter
  continueOnError: false
  description: Filter results by department
  inputs:
    data: mongodb
      department.keyword: DIGITAL COMMUNICATIO
- id: replaceWords
  use: replaceWords
  continueOnError: false
  description: Replaces iphone word to iphone 11 apple
  inputs:
    data:
      iphone: iphone 11 apple
- id: boostByScore
  use: boost
  continueOnError: false
  inputs:
    dataField: categoryPath.name
    value: [cell Phones, Prepaid Phones] 
    boostType: score
- id: promoteResults
  use: boost
  continueOnError: false
  inputs:
    dataField: albumTitle
    value: [Galaxy Note10+]
    boostType: promote
    boostMaxDocs: 1
- use: reactivesearchQuery
  continueOnError: false
- use: elasticsearchQuery
  continueOnError: false

Create the pipeline

Now that we have the whole pipeline defined, we can create the pipeline by hitting the ReactiveSearch instance.

The URL we will hit is: /_pipeline with a POST request.

The above endpoint expects a multipart/form-data body with the pipeline key containing the path to the pipeline file. All the scriptRef files can be passed as a separate key in the form data and will be parsed by the API automatically. Read more about this endpoint here

We can create the pipeline in the following request:

Below request assumes all the files mentioned in this guide are present in the current directory

Copy
curl -X POST 'CLUSTER_URL/_pipeline' -H "Content-Type: multipart/form-data" --form "pipeline=pipeline.yaml"

Testing the Pipeline

We can hit the pipeline endpoint now to see it working live. Use the following request to hit and get the response in the ReactiveSearch format.

Copy
curl -X POST 'CLUSTER_URL/query-boost-example' -H "Content-Type: application/json" -d '{"query": [{"id": "some ID", "value": "sudoku", "dataField": ["name_s"]}]}'

The above request should return a response with search results (considering there are results matching the search term) in the ReactiveSearch format.