Hey @Chris_Bartos,
This is a good question :D. I have been thinking about possible solutions. One I came up with is if you can make start_time
an integer, then I have something that will get you started.
assuming your docs:
POST _bulk
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 0, "taken": false }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 30, "taken": false }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 60, "taken": false }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 90, "taken": false }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 120, "taken": true }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 150, "taken": true }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 180, "taken": false }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 210, "taken": false }
{ "index" : { "_index" : "room_tmp", "_type" : "_doc" } }
{ "room": "room1", "date": "2019-04-01", "start_time": 240, "taken": false }
Here is are some aggregations to get you going. The idea here is we restrict the query to the given day, do a terms agg on the room, and split those up into chunks that match the time you want (in minutes).
GET room_tmp/_search
{
"size": 0,
"query": { // put anything really in the query
"constant_score": {
"filter": {"term": {
"date": "2019-04-01"
}}
}
},
"aggs": {
"by-room": {
"terms": {
"field": "room.keyword",
"size": 10 //Whatever number of rooms...
},
"aggs": {
"every-interval": {
"histogram": {
"field": "start_time",
"interval": 120 // The number of minutes you care about
},
"aggs": {
"num-taken": {
"sum": {
"field": "taken"
}
},
"is-available": {
"bucket_selector": {
"buckets_path": {
"taken": "num-taken"
},
"script": "params.taken == 0" // all the `taken` entries are false
}
}
}
}
}
}
}
}
Something even better would be to make start_time
a date
field type.
PUT room_tmp
{
"mappings" : {
"_doc" : {
"properties" : {
"date" : {
"type" : "date"
},
"room" : {
"type" : "keyword"
},
"start_time" : {
"type" : "date",
"format": "YYYY-MM-DD HH:mm:ss"
},
"taken" : {
"type" : "boolean"
}
}
}
}
}
Example doc:
{ "room": "room1", "date": "2019-04-01", "start_time": "2019-04-01 03:30:00", "taken": false }
Then the agg could be:
GET room_tmp/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {"term": {
"date": "2019-04-01"
}}
}
},
"aggs": {
"by-room": {
"terms": {
"field": "room",
"size": 10
},
"aggs": {
"every-interval": {
"date_histogram": {
"field": "start_time",
"interval": "120m"
},
"aggs": {
"num-taken": {
"sum": {
"field": "taken"
}
},
"is-available": {
"bucket_selector": {
"buckets_path": {
"taken": "num-taken"
},
"script": "params.taken == 0"
}
}
}
}
}
}
}
}