Understanding bool/must behavior (intersection? )


(Frank) #1

I am having trouble getting a bool : must filter to return what I think it should. (I have a gist at http://pastebin.com/e4Mbgq48 )

Given that this returns all 3 records:
Bool:{
must
[
conditionA = true
]
}

and this also Returns all 3 records:
Bool:{
must
[
conditionB = true
]
}

why does this Return NO records:
Bool:{
must
[
conditionA = true
,
conditionB = true
]
}

What am I misunderstanding about bool/must? (elasticsearch 1.6)
thanks
Frank

My Conditions are actually nested key value[] properties that I want to use for aggregation.


(Mike Simos) #2

A bool filter with a must clause, will only return documents that have both conditionA = true and conditionB = true. See this example:

https://www.elastic.co/guide/en/elasticsearch/guide/master/combining-filters.html#_nesting_boolean_filters

So in your above example, if no documents are returned then there is no document that has both conditionA = true and conditionB = true.


(Frank) #4

Mike,
thanks for answering.
But I am confused because I believe my document satisfies both conditions.

I made a new gist ( http://pastebin.com/G8P0LbLP )
that

  • creates an index
  • adds one doc
    -contains 3 queries:
  • the first filters on must[condition A] (and the one doc is returned)
    -the second filters on must[condition B] (the same doc is returned)
    -the third filters on condition must[ A,B] (no hits)

I have no trouble making this work with non-nested properties, but with the nested
properties in my example I get this unexpected result.
Frank


(Mike Simos) #5

Try using something like this:

GET test_attribs/_search
{
  "query": {
    "nested": {
      "path": "attributes",
      "query": {
        "filtered": {
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "attributes.key": "Color"
                  }
                },
                {
                  "term": {
                    "attributes.value": "Blue"
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

(Frank) #6

That works for color, but I would like to add a second set of must's to your example with
key='Type' and value='Autoclavable'. (Since there could be blue things with a type of 'somethingElse' and I need to select only blue, autoclavable types )
since the document contains:
nested attributes:[
{u'key': u'Color', u'value': [u'Black', u'Blue', u'Teal']},
{u'key': u'Type', u'value': [u'Autoclavable']}
]
-would that not also eval to true? It doesn't, and I am not sure why not.

Could it be that only one "key/value" element is examined in a pass - so that if I add to your example a term clause
of "term": { "attributes.key": "Type" } it becomes false because key is already "Color" and can't also be "Type"?

Maybe I need a different index structure to do something like
"select a doc from elasticsearch having an attribute where
( key = color and value= 'Blue')
and also having an attribute where
(key = Type and value= 'Autoclavable'

I am ultimately trying to have dynamic filterable attributes.


(Mike Simos) #7

Hi,

I believe the issue is when using nested documents there is no nested document which has key = color, value= 'Blue, key = Type and value= 'Autoclavable'. What you have is two nested documents one with ( key = color and value= 'Blue') and a second with (key = Type and value= 'Autoclavable'). So this is why the search fails. See this example:

https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html


(Frank) #8

That's my problem, thank you.
I guess I'll have to come up with a different index/mapping or look into dynamic mappings.


(system) #9