0

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" } }
      ]
    }
  }
}
1
  • should will return true if any of the criteria match (name is "Anna" OR age is 30 OR height is 180 OR weight is 70). Is that what you want? If you want all the criteria to match (AND query), you should use must instead of should. Commented Jul 26, 2022 at 12:54

3 Answers 3

2

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
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

If you want a condition that is always false, match_none might be a better choice.
@markusk Good point!
Works perfectly for me... Can you update your question with the commands you've run?
What does the """ behind source mean?
You need to copy/paste and run this in Dev Tools. """ ... """ is supported in Kibana to store non-JSON content, i.e. the search template.
|
0

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.

Comments

0

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);
          """
        }
      }
    }
  }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.