Parent-child relationship "has_child" bool issue


(Tom Coates) #1

Hi,

I am trying to find a property that has available resources for a given date range.

A property can have many resources and a resource can have many reservations.

I am using a parent-child relationship to join the types in the following way..

{
  "availability": {
    "aliases": {},
    "mappings": {
      "reservation": {
        "_parent": {
          "type": "resource"
        },
        "_routing": {
          "required": true
        },
        "properties": {
          "duration": {
            "type": "date_range"
          }
        }
      },
      "property": {
        "properties": {
          "name": {
            "type": "text"
          },
        }
      },
      "resource": {
        "_parent": {
          "type": "property"
        },
        "_routing": {
          "required": true
        },
        "properties": {
          "name": {
            "type": "text"
          }
        }
      }
    }
  }
}

I am then adding the documents with a bulk insert

POST http://localhost:9200/availability/_bulk
{ "index" : { "_type" : "property", "_id": 1 } }
{ "name" : "Hoopers Farm" }
{ "index" : { "_type" : "resource", "_id": 1, "_parent" : 1 } }
{ "name": "The old barn" }
{ "index" : { "_type" : "reservation", "_id": 1, "_parent" : 1 } }
{ "duration": { "gte": "2017-10-31T12:00:00Z", "lte": "2017-11-01T11:59:00Z" } }
{ "index" : { "_type" : "reservation", "_id": 2, "_parent" : 1 } }
{ "duration": { "gte": "2017-11-05T12:00:00Z", "lte": "2017-11-10T11:59:00Z" } }
{ "index" : { "_type" : "resource", "_id": 2, "_parent" : 1 } }
{ "name": "The old farmhouse" }
{ "index" : { "_type" : "reservation", "_id": 3, "_parent" : 2 } }
{ "duration": { "gte": "2017-10-31T12:00:00Z", "lte": "2017-11-04T11:59:00Z" } }
{ "index" : { "_type" : "reservation", "_id": 4, "_parent" : 2 } }
{ "duration": { "gte": "2017-11-05T12:00:00Z", "lte": "2017-11-10T11:59:00Z" } }

And searching for available properties with the following search

POST http://localhost:9200/availability/property/_search
{
  "query": {
    "has_child": {
      "type": "resource",
	    "inner_hits": {},
      "query": {
        "bool": {
          "must_not": {
            "has_child": {
              "type": "reservation",
              "query": {
                "bool": {
                  "filter": {
                    "range": {
                      "duration": {
                        "gte": "2017-10-30T12:00:00Z",
                        "lte": "2017-11-15T11:59:00Z"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

With the above search I'd expect no properties to be returned, but the property is coming back with the second resource in the inner_hits even thought there is reservations for the searched date range on the second resource.

It seems that only the first child resource actually gets queried correctly.

Is there anything obvious that I am doing wrong here?

Many thanks!
Tom


(Tom Coates) #2

Xylakant over on the IRC channel helped me with this in the end.

In the the scenario above I have a grandparent, parent and child type.

The problem was that my child type was not guaranteed to end up on the same shard as the grandparent.

This meant my child could not be queried as the documents from each generation did not end up on the same shard.

With my new found knowledge and the search terms needed I found this guide that documents exactly what I was trying to do and how to do it. :roll_eyes:

https://www.elastic.co/guide/en/elasticsearch/guide/current/grandparents.html


(system) #3

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.