I am planning to store million of airbnb type apartments availabilty in elasticsearch .
Where availabilty is an array that contains nested objects (availability type is nested).
And each of those objects have date range, in which that apartment is available.
apartments = [
{
"_id": "kjty873yhekrg789e7r0n87e",
"first_available_date": "2016-06-21",
"availability": [
{
"start": "2016-06-21",
"end": "2016-08-01"
},
{
"start": "2016-08-20",
"end": "2016-08-28"
},
{
"start": "2016-10-03",
"end": "2016-11-02"
},
{ //This means it is available only for one day.
"start": "2016-11-13",
"end": "2016-11-13"
},
{
"start": "2016-11-28",
"end": "2017-01-14"
}
],
"apartment_metadata1": 56456,
"apartment_metadata2": 8989,
"status": "active"
},
{
"_id": "hgk87783iii86937jh",
"first_available_date": "2016-06-09",
"availability": [
{
"start": "2016-06-09",
"end": "2016-07-02"
},
{
"start": "2016-07-21",
"end": "2016-12-19"
},
{
"start": "2016-12-12",
"end": "2017-07-02"
}
],
"apartment_metadata1": 23534,
"apartment_metadata2": 24377,
"status": "active"
}
]
I would want to search apartments those are available for a specific date range (say 2016-08-20 to 2016-12-12). And that
range should fall inside one of the availability date ranges of various apartments.
So I want to write a query, something like:
{
"query": {
"bool": {
"must": [
{
"range": { "first_available_date": {"lte": "2016-08-20"} },
"match": { "status": "active" }
}
]
},
"filter": [
{
"range":
{
"apartments.availability.start": {"gte": "2016-08-20"},
"apartments.availability.end": {"lte": "2016-12-12"}
}
}
]
}
}
}
And above query will return me both apartments (with MULTIPLE availability objects matching the condition),
and that is incorrect, it should only return document with _id: hgk87783iii86937jh as there is EXACTLY one availability object matches the creiteria and that is {"start": "2016-07-21", "end": "2016-12-19"}. So in order to have correct result, the condition should be - there should be EXACTLY one availability object in apartment doc
that should match the condition. So how to enforce that there should be EXACTLY one match in the above query? Second question - is my query even correct?