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

如何构建支持模糊匹配与通配符的多字段Elasticsearch查询

实现支持模糊匹配与通配符的多字段Elasticsearch查询

你需要同时支持模糊匹配和子串(通配符)匹配的多字段查询,可以通过以下几种方式实现:

方式一:Bool查询组合Match与Wildcard

为每个目标字段同时添加模糊匹配(match)和通配符匹配(wildcard),通过bool的should逻辑让两种匹配规则并行生效:

GET /document/_search
{
  "query": {
    "bool": {
      "should": [
        // addressRange字段:模糊匹配(允许1次编辑距离)
        {
          "match": {
            "addressRange": {
              "_name": "addressRange_fuzzy",
              "operator": "or",
              "query": "ogsroa",
              "fuzziness": 1
            }
          }
        },
        // addressRange字段:通配符子串匹配
        {
          "wildcard": {
            "addressRange": {
              "_name": "addressRange_wildcard",
              "value": "*ogsroa*"
            }
          }
        },
        // documentNumber字段:模糊匹配(不允许编辑距离)
        {
          "match": {
            "documentNumber": {
              "_name": "documentNumber_fuzzy",
              "operator": "or",
              "query": "ogsroa",
              "fuzziness": 0
            }
          }
        },
        // documentNumber字段:通配符子串匹配
        {
          "wildcard": {
            "documentNumber": {
              "_name": "documentNumber_wildcard",
              "value": "*ogsroa*"
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

说明

  • minimum_should_match:1确保至少有一个匹配规则命中就返回文档(默认值也是1,显式声明更清晰)
  • 通配符*ogsroa*会匹配任意包含该子串的内容,但如果通配符以*开头,会触发全索引扫描,数据量大时性能较差

方式二:使用Query String简化写法

Query String支持在查询语句中直接整合通配符和模糊匹配语法,同时指定多字段查询,写法更简洁:

统一模糊规则的版本

GET /document/_search
{
  "query": {
    "query_string": {
      "fields": ["addressRange", "documentNumber"],
      "query": "*ogsroa*~1",
      "_name": "multi_field_fuzzy_wildcard",
      "default_operator": "or"
    }
  }
}

区分字段模糊规则的版本

如果documentNumber不需要模糊匹配,可拆分查询逻辑:

GET /document/_search
{
  "query": {
    "query_string": {
      "query": "(addressRange:*ogsroa*~1) OR (documentNumber:*ogsroa*)",
      "_name": "multi_field_custom_fuzzy_wildcard",
      "default_operator": "or"
    }
  }
}

说明

  • *ogsroa*表示匹配包含该子串的内容
  • ~1表示允许1次编辑距离的模糊匹配,documentNumber部分去掉~则禁用模糊
  • 同样要注意前缀*带来的性能问题

方式三:使用NGram分词优化性能(推荐)

如果业务允许提前调整索引结构,使用NGram分词器可以从根本上解决子串匹配的性能问题,同时兼容模糊匹配:

1. 创建带NGram分词的索引

PUT /document
{
  "settings": {
    "analysis": {
      "analyzer": {
        "ngram_analyzer": {
          "tokenizer": "ngram_tokenizer"
        }
      },
      "tokenizer": {
        "ngram_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 10
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "addressRange": {
        "type": "text",
        "analyzer": "ngram_analyzer",
        "search_analyzer": "standard"
      },
      "documentNumber": {
        "type": "text",
        "analyzer": "ngram_analyzer",
        "search_analyzer": "standard"
      }
    }
  }
}

2. 执行Match查询(同时支持子串和模糊)

GET /document/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "addressRange": {
              "_name": "addressRange",
              "operator": "or",
              "query": "ogsroa",
              "fuzziness": 1
            }
          }
        },
        {
          "match": {
            "documentNumber": {
              "_name": "documentNumber",
              "operator": "or",
              "query": "ogsroa",
              "fuzziness": 0
            }
          }
        }
      ]
    }
  }
}

说明

  • NGram分词会将字段内容拆分为多个长度3-10的子串,比如"Frogsroad"会被拆分为"Fro"、"rog"、"ogs"等
  • 搜索"ogsroa"时,Match查询会直接匹配分词后的子串,无需通配符,性能远高于Wildcard查询
  • 同时保留fuzziness参数,依然支持模糊匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:57:24