我有要出租的物品。用户指定start_date
和end_date
。每个项目都有多个blocked_periods
以及开始日期和结束日期。
目标:
查询所有可用项目。可以说: 12.11。,13.11。,14.11。,15.11。
封锁的是13和14。
该项目应在12或15或从12到15可用。但是开始日期和结束日期不能在13和14上。
当前索引:
{
"development_items" : {
"aliases" : { },
"mappings" : {
"item" : {
"properties" : {
"blocked_periods" : {
"type" : "nested",
"properties" : {
"end_date" : {
"type" : "date",
"format" : "yyyy-MM-dd"
},
"start_date" : {
"type" : "date",
"format" : "yyyy-MM-dd"
}
}
}
}
}
},
"settings" : {
"index" : {
"creation_date" : "1503327829680",
"number_of_shards" : "5",
"number_of_replicas" : "1",
"uuid" : "9b9BhF-ITta2dlCKRLrnfA",
"version" : {
"created" : "2040499"
}
}
},
"warmers" : { }
}
}
当前查询:
{
bool: {
must_not: {
nested: {
path: 'blocked_periods',
query: {
bool: {
should: [
{
bool: {
must: [
{
range: {
'blocked_periods.start_date': {
lte: start_date
}
}
},
{
range: {
'blocked_periods.end_date': {
gte: end_date
}
}
}
]
}
}
]
}
}
}
}
}
}
答案 0 :(得分:1)
您要记录给定的开始时间不在阻止时间段内并且给定的结束时间不在阻止时间段内。换句话说,这是
您不希望文档中给定的起始时间处于阻止时段或给定的结束时间处于阻止时段(!A AND !B === !(A OR B)
)。
如果我们坚持使用您的映射并以嵌套方式进行操作,请按以下步骤操作:
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "blocked_periods",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"range": {
"blocked_periods.start_date": {
"lte": "START"
}
}
},
{
"range": {
"blocked_periods.end_date": {
"gte": "START"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"blocked_periods.start_date": {
"lte": "END"
}
}
},
{
"range": {
"blocked_periods.end_date": {
"gte": "END"
}
}
}
]
}
}
]
}
}
}
}
]
}
}
}
但是,如果您可以处理将字段名从start_date/end_date
更改为gte/lte
的问题,我认为您会发现date_range方法更可取。
PUT my_index
{
"mappings": {
"item": {
"properties": {
"blocked_periods": {
"type": "date_range",
"format": "yyyy-MM-dd"
}
}
}
}
}
POST my_index/item/1
{
"blocked_periods": [
{
"gte": "2020-1-10",
"lte": "2020-1-15"
},
{
"gte": "2020-1-17",
"lte": "2020-1-25"
}
]
}
GET my_index/_search
{
"query": {
"bool": {
"must_not": [
{
"term": {
"blocked_periods": "START"
}
},
{
"term": {
"blocked_periods": "END"
}
}
]
}
}
}