【问题标题】:Combine elasticsearch bool query with range boost将弹性搜索布尔查询与范围提升相结合
【发布时间】:2017-06-09 17:37:24
【问题描述】:

将 elasticsearch bool 查询与范围提升相结合

我有一个复杂的bool 查询如下。我使用虚假搜索词 dgbdrtgndgfndrtgb 来编造我的示例,它不应该匹配任何内容。

{
  "from": 0,
  "size": 10,
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "query": {
        "filtered": {
          "filter": {
            # ...
          },
          "query": {
            "bool": {
              "should": [
                {
                  "match": {
                    "name.suggest_ngrams": {
                      "query": "dgbdrtgndgfndrtgb",
                      "fuzziness": "AUTO",
                      "prefix_length": 1,
                      "operator": "AND",
                      "boost": 10
                    }
                  }
                },
                {
                  "multi_match": {
                    "query": "dgbdrtgndgfndrtgb",
                    "fields": [
                      "name.untouched_lowercase"
                    ],
                    "boost": 5
                  }
                },
                {
                  "query_string": {
                    "fields": [
                      "name.suggest"
                    ],
                    "query": "dgbdrtgndgfndrtgb*",
                    "boost": 10
                  }
                },
                {
                  "query_string": {
                    "fields": [
                      "name.suggest"
                    ],
                    "query": "dgbdrtgndgfndrtgb",
                    "boost": 10
                  }
                },
                {
                  "match": {
                    "first_word": {
                      "query": "dgbdrtgndgfndrtgb",
                      "operator": "AND",
                      "boost": 10
                    }
                  }
                },
                {
                  "match": {
                    "name": {
                      "query": "dgbdrtgndgfndrtgb",
                      "operator": "AND",
                      "boost": 5
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

这很好用。现在,对于这些匹配中的任何一个,我想添加一个boost,其中name 字段的字数少于2 个。换句话说,提升单字匹配或将它们排序到结果集的顶部。

所以我尝试像这样添加range 提升:

{
  "from": 0,
  "size": 10,
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "query": {
        "filtered": {
          "filter": {
            # ...
          },
          "query": {
            "bool": {
              "should": [
                {
                  "match": {
                    "name.suggest_ngrams": {
                      "query": "dgbdrtgndgfndrtgb",
                      "fuzziness": "AUTO",
                      "prefix_length": 1,
                      "operator": "AND",
                      "boost": 10
                    }
                  }
                },
                {
                  "multi_match": {
                    "query": "dgbdrtgndgfndrtgb",
                    "fields": [
                      "name.untouched_lowercase"
                    ],
                    "boost": 5
                  }
                },
                {
                  "query_string": {
                    "fields": [
                      "name.suggest"
                    ],
                    "query": "dgbdrtgndgfndrtgb*",
                    "boost": 10
                  }
                },
                {
                  "query_string": {
                    "fields": [
                      "name.suggest"
                    ],
                    "query": "dgbdrtgndgfndrtgb",
                    "boost": 10
                  }
                },
                {
                  "match": {
                    "first_word": {
                      "query": "dgbdrtgndgfndrtgb",
                      "operator": "AND",
                      "boost": 10
                    }
                  }
                },
                {
                  "match": {
                    "name": {
                      "query": "dgbdrtgndgfndrtgb",
                      "operator": "AND",
                      "boost": 5
                    }
                  }
                },
                { 
                  "range": {
                    "name.word_count": {
                      "lt": 2,
                      "boost": 40
                    }
                  }
                }               
              ]
            }
          }
        }
      }
    }
  }
}

这对我想要的东西进行排序,但它也返回与搜索词 dgbdrtgndgfndrtgb 不匹配的单个单词匹配项。

有没有办法只提升单字匹配,这也匹配搜索词?我尝试降低 boost 值,这会在使用有效(找到)搜索词时破坏所需的排序。

似乎应该有一种方法可以通过 range 提升 AND 整个 bool 查询。我已经尝试了各种排列来实现这一点,但没有运气,文档也没什么帮助。

一个警告:我不能使用脚本,因为索引托管在不支持它的 AWS 上。

感谢任何建议。

【问题讨论】:

    标签: elasticsearch querydsl


    【解决方案1】:

    在解决这个问题后,我突然意识到这只是布尔逻辑。因此,我想出了这个完美运行的解决方案,其中我将工作查询逻辑包装在 must 标记中,并将 range 提升放在 should 标记中。

    {
      "from": 0,
      "size": 10,
      "query": {
        "function_score": {
          "boost_mode": "replace",
          "query": {
            "filtered": {
              "filter": {
                # ...
              },
              "query": {
                "bool": {
                  "must": {
                    "bool": {
                      "should": [
                        {
                          "match": {
                            "name.suggest_ngrams": {
                              "query": "dgbdrtgndgfndrtgb",
                              "fuzziness": "AUTO",
                              "prefix_length": 1,
                              "operator": "AND",
                              "boost": 10
                            }
                          }
                        },
                        {
                          "multi_match": {
                            "query": "dgbdrtgndgfndrtgb",
                            "fields": [
                              "name.untouched_lowercase"
                            ],
                            "boost": 5
                          }
                        },
                        {
                          "query_string": {
                            "fields": [
                              "name.suggest"
                            ],
                            "query": "dgbdrtgndgfndrtgb*",
                            "boost": 10
                          }
                        },
                        {
                          "query_string": {
                            "fields": [
                              "name.suggest"
                            ],
                            "query": "dgbdrtgndgfndrtgb",
                            "boost": 10
                          }
                        },
                        {
                          "match": {
                            "first_word": {
                              "query": "dgbdrtgndgfndrtgb",
                              "operator": "AND",
                              "boost": 10
                            }
                          }
                        },
                        {
                          "match": {
                            "name": {
                              "query": "dgbdrtgndgfndrtgb",
                              "operator": "AND",
                              "boost": 5
                            }
                          }
                        }
                      ]
                    }
                  },
                  "should": {
                    "range": {
                      "name.word_count": {
                        "lt": 2,
                        "boost": 40
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    

    耶!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 2013-06-06
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多