【问题标题】:Find one result based on a term query or a list of results based on a match query基于术语查询或基于匹配查询的结果列表查找一个结果
【发布时间】:2020-06-19 18:03:42
【问题描述】:

我有一个文档索引,每个文档都包含一个 idname 字段。每个文档name 恰好是唯一的。

我想对name 字段执行查询,如果可能返回一个确切的结果,或者返回一个类似结果的列表。例如,如果搜索词是 Acme Incorporated 并且有准确的结果,则仅返回该结果。否则返回相似匹配;例如:ACME Inc.acmeAce

我假设我需要以某种方式组合基于关键字的术语查询以进行精确匹配,并以基于文本的匹配查询进行类似匹配。我仍在处理复合查询,所以我的第一次尝试非常天真:

{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "name.exact": "Acme Incorporated"
          }
        },
        {
          "match": {
            "name": "Acme Incorporated"
          }
        }
      ]
    }
  }
}

这将返回一个相似匹配列表和一个精确匹配(如果存在),因为至少有一个查询应该成功。这显然是不正确的。

为了方便上面基于关键字的词条查询,我在我的文档映射中添加了name.exact

{
  "mappings": {
    "properties": {
      "id": {
        "type": "integer"
      },
      "name": {
        "type": "text",
        "fields": {
          "exact": { 
            "type":  "keyword"
          }
        }
      }
    }
  }
}

我想另一种方法是使用Multi Search API 分别执行上述查询。这使我可以查看响应,并在术语查询结果集为空时决定使用匹配查询。这适用于我的用例,但我怀疑这不是最佳方法。

我认为这是一个常见的用例,但我不确定解决方案是什么。

编辑

我目前对此的想法是我使用如上所述的多搜索查询,第一个是基于相同关键字的术语查询以尝试找到确切的结果,第二个是以下 - 复合 bool排除精确结果的查询。

{
  "query": {
    "bool": {
      "must": {
        "match": {
          "name": "Acme Incorporated"
        }
      },
      "must_not": {
        "term": {
          "name.keyword": "Acme Incorporated"
        }
      }
    }
  }
}

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    最后,MultiSearch API 适合我的用例:

    多搜索 API 从单个 API 请求执行多个搜索。请求的格式类似于批量 API 格式,并使用换行符分隔的 JSON (NDJSON) 格式。

    我用它在一个请求中执行两个查询:

    1. 在文档name 字段上使用基于关键字的term 查询查找任何确切结果。
    2. 使用bool 查询查找任何类似的结果,包括match 查询 记录name 字段,以及第一个查询的must_not 过滤掉任何确切的结果。

    多重搜索正文由一对或多对(可选)空标题和正文(单个查询)组成,由换行符分隔;例如:

    GET /myindex/_msearch
    {}
    {"query": {"constant_score": {"filter": {"term": {"name.keyword": "Acme Incorporated"}}}}}
    {}
    {"query": {"bool": {"must": {"match": {"name": "Acme Incorporated"}}, "must_not": {"term": {"name.keyword": "Acme Incorporated"}}}}}
    
    

    查询采用ndjson 格式,表示“每一行都是一个有效的 JSON 值”。这要求将每个查询压缩到一行,这不是很可读,但如果您使用库来构造查询,这不是问题。

    【讨论】:

    • 我仍然很高兴听到替代方法,所以我会暂时不回答这个问题:) 谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多