Home > Mobile >  Is there a way to build an Elastic query with changing search values?
Is there a way to build an Elastic query with changing search values?

Time:07-27

I want to use Elastic in PHP to process a search request from my website. For example, I have the search parameter

  • name
  • age
  • height
  • weight.

But it should not be necessary to always search for all parameters.

So it could be that only (name AND age) have values and (height AND weight) have not.

Is there a way to build one query with flexible/changing input values?

The query below would not work when there are no search values for (height AND weight).

{
  "query": {
    "bool": {
      "should": [
        { "match": { "name.keyword": "Anna" } },
        { "match": { "age": "30" } },
        { "match": { "height": "180" } },
        { "match": { "weight": "70" } }
      ]
    }
  }
}

CodePudding user response:

Search templates to the rescue:

POST _scripts/my-search-template
{
  "script": {
    "lang": "mustache",
    "source": """
    {
      "query": {
        "bool": {
          "should": [
            {{#name}}
             { "match": { "name.keyword": "{{name}}" } },
            {{/name}}
            {{#age}}
             { "match": { "age": "{{age}}" } },
            {{/age}}
            {{#height}}
             { "match": { "height": "{{height}}" } },
            {{/height}}
            {{#weight}}
             { "match": { "weight": "{{weight}}" } },
            {{/weight}}
             { "match_none": { } }
          ]
        }
      }
    }
  }
}

Note that since you don't know how many criteria you have, the last condition is always false and is only there to make sure the JSON is valid (i.e. the last comma doesn't stay dangling)

You can then run your query like this:

POST my-index/_search/template
{
  "id": "my-search-template",
  "params": {
    "name": "Anna",
    "age": 30
  }
}

CodePudding user response:

You need to handle in your application that constructs your Elasticsearch query and its very easy to do it in the application as you know what all search parameter value you got from UI, if they are not null than only includes those fields in your Elasticsearch query.

Elasticsearch doesn't support if...else like condition in query.

CodePudding user response:

Tldr;

They are multiple way to address your problem in Elasticsearch.

You could be playing with the parameter minimum_should_match

You could be using template queries with conditions.

You could also perform more complex bool queries, that enumerate the possibilities for a match.

You could also use scripts to program the logic you want to see.

Minimum should match

POST /_bulk
{"index":{"_index":"73121817"}}
{"name": "ana", "age": 1, "height": 180, "weight": 70}
{"index":{"_index":"73121817"}}
{"name": "jack", "height": 180, "weight": 70}
{"index":{"_index":"73121817"}}
{"name": "emma", "age": 1, "weight": 70}
{"index":{"_index":"73121817"}}
{"name": "william", "age": 1, "height": 180}
{"index":{"_index":"73121817"}}
{"name": "jenny", "weight": 70}
{"index":{"_index":"73121817"}}
{"name": "marco", "age": 1}
{"index":{"_index":"73121817"}}
{"name": "giulia", "height": 180}
{"index":{"_index":"73121817"}}
{"name": "paul"}


GET 73121817/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "name.keyword": "Anna" } },
        { "match": { "age": "30" } },
        { "match": { "height": "180" } },
        { "match": { "weight": "70" } }
      ],
      "minimum_should_match": 2
    }
  }
}

with the minimum should match set to 2 only 2 documents are returned ana and jack

Template queries

Well Val's answer is quite complete

You could also refer to the doc

Complex queries

Refer to the so post behind the link

Scripted queries

GET 73121817/_search
{
  "query": {
    "bool": {
      "filter": {
        "script": {
          "script": """
            return (!doc["name.keyword"].empty && !doc["age"].empty);
          """
        }
      }
    }
  }
}
  • Related