【问题标题】:How to make a bool query with must over multiple fields in ElasticSearch?如何在 ElasticSearch 中的多个字段上进行 bool 查询?
【发布时间】:2017-10-22 05:38:09
【问题描述】:

很抱歉这个菜鸟问题,但 ElasticSearch 查询可能会令人困惑......

目标:创建一个类似于 Google 搜索查询的查询。您输入的单词越多,您获得的匹配结果就越少。例如,“四川酱”比“木兰四川酱”产生更多的结果。 我的索引有一个博客文章类型,其中包含“标题”、“标签”、“类别”等字段。 ElasticSearch 必须找到与查询中的所有单词匹配的每个文档。这些词可以遍布所有领域。例如,如果一个文档的标题包含“mulan”,其标签包含“szechuan”,其类别包含“sauce”,那么这应该是匹配的,但如果缺少一个单词则不是。

我尝试了不同的布尔查询,但即使我使用“必须”,结果也会包含与所有查询词都不匹配的文档。

例如我试过:

String queryString = "mulan szechuan sauce";
QueryBuilder titleMatchQuery = QueryBuilders.matchQuery("title", queryString);
QueryBuilder tagsMatchQuery = QueryBuilders.matchQuery("tags", queryString);
QueryBuilder categoryMatchQuery = QueryBuilders.matchQuery("categories", queryString);
QueryBuilder combinedBoolQuery = QueryBuilders.boolQuery()
    .must(titleMatchQuery)
    .must(tagsMatchQuery)
    .must(categoryMatchQuery);

这编译为:

{
  "bool" : {
    "must" : [ {
      "match" : {
        "title" : {
          "query" : "mulan szechuan sauce",
          "type" : "boolean"
        }
      }
    }, {
      "match" : {
        "tags" : {
          "query" : "mulan szechuan sauce",
          "type" : "boolean"
        }
      }
    }, {
      "match" : {
        "categories" : {
          "query" : "mulan szechuan sauce",
          "type" : "boolean"
        }
      }
    } ]
  }
}

如前所述,这也会产生不包含查询中所有单词的结果:-/

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    改用multi_match 就好了:

    String queryString = "mulan szechuan sauce";
    QueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(queryString, 
        "title", "tags", "categories");
    QueryBuilder combinedBoolQuery = QueryBuilders.boolQuery()
        .must(multiMatchQuery);
    

    【讨论】:

    • 谢谢,但这不能按预期工作。仍然有不包含所有单词的结果。
    • 您添加的链接带来了答案:D - 要完成这项工作,我们需要添加 AND 运算符。对于 Java:QueryBuilders.multiMatchQuery(queryString, "title", "tags", "category").operator(MatchQueryBuilder.Operator.AND)
    • 很高兴它有帮助!
    • 它可能关注的对象:如果我们只添加 AND 运算符,那么 ElasticSearch 默认使用“best_fields”类型。这意味着“所有术语必须出现在单个字段中以使文档匹配”(请参阅​​答案中提供的链接)。如果多个字段应该匹配,那么我们需要使用“cross_fields”-type。对于 Java,它只是将 ´.type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)´ 添加到 QueryBuilder。
    猜你喜欢
    • 2016-07-20
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 2020-02-26
    • 2022-06-29
    • 1970-01-01
    相关资源
    最近更新 更多