【问题标题】:Combining nested query with boolean query in Elastic Search在 Elastic Search 中将嵌套查询与布尔查询相结合
【发布时间】:2019-08-11 14:04:44
【问题描述】:

我正在尝试在 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 美元之间的房间。

所以我想出了这个逻辑:

  1. customPrices.date 必须介于 2019-07-01 和 2019-07-07 之间,customPrices.price 必须介于 100 和 200 之间。
  2. 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 来理​​解为什么特定文档不匹配但我不明白,它说 user requested match_none 查询但是有这个 should 查询所以它应该匹配嵌套查询(第一个):

{
  "_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": []
          }
        ]
      }
    ]
  }
}

非常感谢任何帮助或想法...

【问题讨论】:

    标签: elasticsearch elasticsearch-nested


    【解决方案1】:

    如果您仔细查看第一个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"
                                              }
                                           }
                                        }
                                     }
                                  }
                               ]
                            }
                         }
                      ]
                   }
                }
             ]
          }
       }
    }
    

    希望对你有帮助!

    【讨论】:

    • 嘿@madpoet,以上是否解决了您遇到的问题。您还在寻找其他东西吗?
    • 很好奇为什么您在嵌套查询周围同时有 shouldmustmust 本身就可以吗?
    • 嗯,最初我想过,但也许 OP 必须有一个他没有透露的更复杂的查询。我刚刚与他分享了与他陷入困境的问题有关的确切解决方案。它还取决于查询的深度,例如如果他在不同深度有多个shouldmust 子句怎么办。也许这就是为什么我认为他知道自己在做什么并与他分享他遇到的问题的解决方案。我在更深层次上看到了更复杂的查询,我会让他怀疑它的好处。
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 2019-04-03
    • 2011-02-19
    相关资源
    最近更新 更多