Search code examples
elasticsearchboolean-logicbooleanquery

How to properly write boolean or logic in elasticsearch?


I want to grab all documents with loId=6 AND (actionType = "SAVE_DATA" OR actionType = "OPEN_SCREEN").

Am I writing this logic incorrectly?

Why does my query return 0 results?

Note: I'd accept a query or a filter to resolve this issue.

These are some sample documents:

 {
    "_index": "logs",
    "_type": "record",
    "_id": "eIIt3vtrSxmdOVGClQmN3w",
    "_score": 1,
    "_source": {
       "timestamp": 1373569919000,
       "uid": 6,
       "paId": 56298,
       "loId": 6,
       "prId": 2,
       "vId": 6577,
       "actionType": "SAVE_DATA"
    }
 },
 {
    "_index": "logs",
    "_type": "record",
    "_id": "yQGCia6qRYCImZLyH7DrEA",
    "_score": 1,
    "_source": {
       "timestamp": 1373570314000,
       "uid": 6,
       "paId": 56641,
       "loId": 6,
       "prId": 2,
       "vId": 6578,
       "actionType": "CHECK_IN"
    }
 },
 {
    "_index": "logs",
    "_type": "record",
    "_id": "2raajrNKTKeRKG88wiNPpw",
    "_score": 1,
    "_source": {
       "timestamp": 1373570532000,
       "uid": 6,
       "paId": 56641,
       "loId": 6,
       "prId": 2,
       "vId": 6579,
       "actionType": "LOAD_DATA"
    }
 },
 {
    "_index": "logs",
    "_type": "record",
    "_id": "0FDBxW2ESl6tfmj81YJvIg",
    "_score": 1,
    "_source": {
       "timestamp": 1373570761000,
       "uid": 6,
       "paId": 56298,
       "loId": 6,
       "prId": 2,
       "vId": 6577,
       "actionType": "OPEN_SCREEN"
    }
 },
 {
    "_index": "logs",
    "_type": "record",
    "_id": "-bFQyEdCQVWiXNldtxz04g",
    "_score": 1,
    "_source": {
       "timestamp": 1373570777000,
       "uid": 6,
       "paId": 56298,
       "loId": 6,
       "prId": 2,
       "vId": 6577,
       "actionType": "OPEN_SCREEN"
    }
 }

Query

{
   "query": {
      "filtered": {
          "query": {
              "term": {
                    "loId": 6
              }
          }, 
         "filter": {
            "or": {
               "filters": [
                  {
                     "term": {
                        "actionType": "SAVE_DATA"
                     }
                  },
                  {
                     "term": {
                        "actionType": "OPEN_SCREEN"
                     }
                  }
               ],
               "_cache": false
            }
         }
      }
   }
}

Solution

  • The main reason you're having trouble getting results is because you're trying to do a term filter on actionType, which is an analyzed field. If you want to do term matching on that field, you'll need to update your type mapping to set that field to not_analyzed. See this example mapping:

    {
       "record": {
          "properties": {
             "actionType": {
                "type": "string",
                "index": "not_analyzed",
             },
             "loId": {
                "type": "long"
             },
             "paId": {
                "type": "long"
             },
             "prId": {
                "type": "long"
             },
             "timestamp": {
                "type": "long"
             },
             "uid": {
                "type": "long"
             },
             "vId": {
                "type": "long"
             }
          }
       }
    } 
    

    Read up on mappings starting here: http://www.elasticsearch.org/guide/reference/mapping/. You'll need to reindex your data. With that fixed, here's a query that will work:

    { 
        "query": { 
            "filtered": {
               "query": {"match_all":{}},
               "filter": {
                   "bool": {
                       "must": [
                           {"term": {"loId":6}},
                           {
                               "or": [
                                   {"term":{"actionType": "SAVE_DATA"}},
                                   {"term":{"actionType": "OPEN_SCREEN"}}
                               ]
                           }
                       ]
                   }
               }
            }
        }
    }