Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElasticSearch multi_match if field exists apply filter otherwise dont worry about it?

So we got an elasticsearch instance, but a job is requiring a "combo search" (A single search field, with checkboxes for types across a specific index)

This is fine, I simply apply this kind of search to my index (for brevity: /posts):

{
    "query": {
        "multi_match": {
            "query": querystring, 
            "type":"cross_fields",
            "fields":["title","name"] 
            }
        } 
    }
}

As you may guess from the need for the multi_match here, the schemas to each of these types differs in one way or another. And that's my challenge right now.

In one of the types, just one, there is a field that doesnt exist in the other types, it's called active and it's a basic boolean 0 or 1.
We want to index inactive items in the type for administration search purposes, but we don't want inactive items in this type to be exposed to the public when searching.

To my knowledge and understanding, I want to use a filter. But when I supply a filter asking for active to be 1, I only ever now get results from that type and nothing else. Because now it's explicitly looking for items with that field and equal to one.

How can I do a conditional "if field exists, make sure it equals 1, otherwise ignore this condition"? Can this even be achieved?

like image 201
RedactedProfile Avatar asked Oct 29 '15 01:10

RedactedProfile


1 Answers

if field exists, make sure it equals 1, otherwise ignore this condition

I think it can be implemented like this:

{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "exists": {
                      "field": "active"
                    }
                  },
                  {
                    "term": {
                      "active": 1
                    }
                  }
                ]
              }
            },
            {
              "missing": {
                "field": "active"
              }
            }
          ]
        }
      }
    }
  }
}

and the complete query:

{
  "query": {
    "filtered": {
      "query": {
        "multi_match": {
          "query": "whatever",
          "type": "cross_fields",
          "fields": [
            "title",
            "name"
          ]
        }
      },
      "filter": {
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "exists": {
                      "field": "active"
                    }
                  },
                  {
                    "term": {
                      "active": 1
                    }
                  }
                ]
              }
            },
            {
              "missing": {
                "field": "active"
              }
            }
          ]
        }
      }
    }
  }
}
like image 93
Andrei Stefan Avatar answered Dec 30 '22 15:12

Andrei Stefan