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

时间:2017-01-24 18:31:21

标签: elasticsearch querydsl

将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值,这会在使用有效(找到)搜索字词时中断所需的排序。

似乎应该通过AND提升bool range整个 <div class="container"> <div class="row"> <div class="col-md-6"></div> </div> </div> 查询。我已经尝试了各种排列来实现这一目标而没有运气,而且文档也没那么有用。

有一点需要注意:我不能使用脚本,因为索引托管在不支持它的AWS上。

感谢任何建议。

1 个答案:

答案 0 :(得分:0)

在问题上睡觉之后,我发现它只是布尔逻辑。所以,我提出了这个完美运行的解决方案,其中我将工作查询逻辑包装在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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

耶!