You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch如何实现文档字段值被包含在搜索短语的精确匹配?

实现文档字段值被搜索短语完整包含的精确匹配(Elasticsearch)

索引结构

示例文档的_source结构如下:

"_source": {
  "iD": "378",
  "containsTerms": [
    {
      "containsTerm": "search term to match"
    },
    {
      "containsTerm": "another search term to match"
    },
    {
      "containsTerm": "etcetera"
    }
  ],
  "startdate": "2022-09-08T14:07:00",
  "enddate": "2022-09-30T14:07:00"
}

字段映射

该索引的映射配置:

"mappings":{
   "properties":{
      "containsTerms":{
         "properties":{
            "containsTerm":{
               "type":"text",
               "fields":{
                  "keyword":{
                     "type":"keyword",
                     "ignore_above":256
                  }
               }
            }
         }
      },
      "enddate":{
         "type":"date"
      },
      "startdate":{
         "type":"date"
      }
   }
}

原有查询的局限性

之前使用的match查询会返回包含搜索短语部分内容(如"search"、"search term")或更长匹配短语的文档:

{
   "query":{
      "bool":{
         "must":[
            {
               "match":{
                  "containsTerms.containsTerm":{
                     "query":"search term to match"
                  }
               }
            },
            {
               "range":{
                  "startdate":{
                     "lte":"2022-09-22T14:43:38"
                  }
               }
            },
            {
               "range":{
                  "enddate":{
                     "gte":"2022-09-22T15:43:38"
                  }
               }
            }
         ]
      }
   }
}

若改用keyword类型的精确匹配,则仅当搜索内容与字段值完全一致时才返回结果,无法满足搜索短语完整包含文档字段值即匹配的需求(例如搜索"blah blah search term to match blah blah"需返回文档,而"blah blah search term to blah blah"则不返回)。

可行的解决方案

可以通过以下两种方式实现需求:

方法1:Script查询

通过脚本遍历文档中的containsTerm.keyword值,判断是否存在被搜索短语包含的项:

{
  "query": {
    "bool": {
      "must": [
        {
          "script": {
            "script": {
              "source": """
                def searchPhrase = params.searchPhrase;
                for (def term : doc['containsTerms.containsTerm.keyword']) {
                  if (searchPhrase.contains(term.value)) {
                    return true;
                  }
                }
                return false;
              """,
              "params": {
                "searchPhrase": "blah blah search term to match blah blah"
              }
            }
          }
        },
        {
          "range": {
            "startdate": {
              "lte": "2022-09-22T14:43:38"
            }
          }
        },
        {
          "range": {
            "enddate": {
              "gte": "2022-09-22T15:43:38"
            }
          }
        }
      ]
    }
  }
}

该脚本会逐一检查文档中所有containsTerm的精确值,只要有一个值被搜索短语包含,就会匹配该文档。

方法2:Wildcard查询

将搜索短语作为通配符模式的中间部分,匹配字段值是否为搜索短语的子串:

{
  "query": {
    "bool": {
      "must": [
        {
          "wildcard": {
            "containsTerms.containsTerm.keyword": {
              "value": "*blah blah search term to match blah blah*"
            }
          }
        },
        {
          "range": {
            "startdate": {
              "lte": "2022-09-22T14:43:38"
            }
          }
        },
        {
          "range": {
            "enddate": {
              "gte": "2022-09-22T15:43:38"
            }
          }
        }
      ]
    }
  }
}

注意:如果通配符模式以*开头,会导致查询性能下降,数据量较大时优先选择Script查询。

内容的提问来源于stack exchange,提问作者DaveSav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:25:15