我正在尝试在 Elastic Search 中按价格范围过滤酒店房间。房间有默认的每晚价格,也可以为特定日期设置自定义价格。
我正在存储 nightlyPrice
和自定义价格的嵌套对象以及日期。映射是smt。像:
{
"adverts": {
"mappings": {
"advert": {
"properties": {
"nightlyPrice": {"type": "float"},
"customPrices": {
"type": "nested",
"properties": {
"date": {"type": "date"},
"price": {"type": "float"}
}
}
}
}
}
}
}
例如,我想在 7 月 1 日到 7 日期间获得价格在 100 到 200 美元之间的房间。
所以我想出了这个逻辑:
customPrices.date
必须介于 2019-07-01 和 2019-07-07 之间,并且customPrices.price
必须介于 100 到 200 之间。- 或者
nightlyPrice
必须介于 100 到 200 之间,并且在 7 月 5 日到 7 日期间没有设置customPrices.date
。
但是我无法将此逻辑应用于 Elastic Search,我猜嵌套对象/查询有点棘手。
这是我提出的最终查询:
{
"query": {
"bool": {
"filter": [
{
"term": {
"status": "active"
}
}
],
"must": [
{
"bool": {
"should": [
{
"nested": {
"path": "customPrices",
"query": {
"bool": {
"must": [
{
"range": {
"date": {
"from": "2019-07-01",
"to": "2019-07-07"
}
}
},
{
"range": {
"price": {
"from": 100,
"to": 200
}
}
}
]
}
}
}
},
{
"bool": {
"must": [
{
"range": {
"nightlyPrice": {
"from": 100,
"to": 200
}
}
}
],
"must_not": [
{
"nested": {
"path": "customPrices",
"query": {
"range": {
"customPrices.date": {
"from": "2019-07-01",
"to": "2019-07-07"
}
}
}
}
}
]
}
}
]
}
}
]
}
}
}
此查询的问题是,如果 customPrices.date 与日期范围匹配,则无论价格范围如何,它都不会与文档匹配。我尝试了 1 - 100000 美元的价格范围,但仍然不匹配。
尝试使用解释API来理解为什么特定文档不匹配,但我不明白,它说用户请求match_none
查询,但有这个应该
查询,因此它应该与嵌套查询(第一个)匹配:
{
"_index": "adverts",
"_type": "advert",
"_id": "13867",
"matched": false,
"explanation": {
"value": 0.0,
"description": "Failure to meet condition(s) of required/prohibited clause(s)",
"details": [
{
"value": 0.0,
"description": "no match on required clause (+(ToParentBlockJoinQuery (MatchNoDocsQuery(\"User requested \"match_none\" query.\")) (+nightlyPrice:[100.0 TO 200.0] -ToParentBlockJoinQuery (customListingPrices.date:[1561939200000 TO 1562543999999]))) #status:active",
"details": [
{
"value": 0.0,
"description": "Failure to meet condition(s) of required/prohibited clause(s)",
"details": [
{
"value": 0.0,
"description": "no match on required clause (ToParentBlockJoinQuery (MatchNoDocsQuery(\"User requested \"match_none\" query.\")) (+nightlyPrice:[100.0 TO 200.0] -ToParentBlockJoinQuery (customListingPrices.date:[1561939200000 TO 1562543999999])))",
"details": [
{
"value": 0.0,
"description": "No matching clauses",
"details": []
}
]
},
{
"value": 0.0,
"description": "match on required clause, product of:",
"details": [
{
"value": 0.0,
"description": "# clause",
"details": []
},
{
"value": 1.0,
"description": "status:active",
"details": []
}
]
}
]
}
]
},
{
"value": 0.0,
"description": "match on required clause, product of:",
"details": [
{
"value": 0.0,
"description": "# clause",
"details": []
},
{
"value": 1.0,
"description": "DocValuesFieldExistsQuery [field=_primary_term]",
"details": []
}
]
}
]
}
}
非常感谢任何帮助或想法...
最佳答案
如果仔细查看第一个 must
子句,您似乎没有提到该字段的完整路径。
{
"range":{
"date":{ <-- must be "customPrices.date"
"from":"2019-07-01",
"to":"2019-07-07"
}
}
},
{
"range":{
"price":{ <-- must be "customPrices.price"
"from":100,
"to":200
}
}
}
下面是查询应该如何并且应该适合您的用例。
查询
POST <your_index_name>/_search
{
"query":{
"bool":{
"filter":{
"term":{
"status":"active"
}
},
"must":[
{
"bool":{
"should":[
{
"bool":{
"must":[
{
"nested":{
"path":"customPrices",
"query":{
"bool":{
"must":[
{
"range":{
"customPrices.date":{
"gte":"2019-07-01",
"lte":"2019-07-09"
}
}
},
{
"range":{
"customPrices.price":{
"gte":100,
"lte":200
}
}
}
]
}
}
}
}
]
}
},
{
"bool":{
"must":[
{
"range":{
"nightlyPrice":{
"gte":100,
"lte":200
}
}
}
],
"must_not":[
{
"nested":{
"path":"customPrices",
"query":{
"range":{
"customPrices.date":{
"gte":"2019-07-05",
"lte":"2019-07-07"
}
}
}
}
}
]
}
}
]
}
}
]
}
}
}
希望对你有帮助!
关于elasticsearch - 在 Elastic Search 中将嵌套查询与 bool 查询相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55268211/