为何Elasticsearch wildcard查询同时匹配bob和smith时无返回结果
问题原因
wildcard查询的匹配规则是针对分词后生成的单个词项(term)做匹配,而非匹配字段的完整原始文本。- 你的
name字段大概率使用了默认的标准分词器,Bob Smith存入索引时会被拆分为bob、smith两个独立的词项存放在倒排索引中,不存在同时包含bob、空格、smith的单个词项。 - 你在Query #2中传入的匹配规则
*bob* *smith*是要求找到单个词项同时匹配「任意字符+bob+任意字符+空格+任意字符+smith+任意字符」,没有符合条件的词项,因此返回结果为空。 - Query #1可以正常返回是因为
*bob*可以匹配到单个词项bob,所以能命中对应文档。
可用解决方案
方案1:拆分多个wildcard条件组合查询
用bool查询将两个通配条件作为并列必须满足的规则,分别匹配两个词项:
GET people/_search { "query": { "bool": { "must": [ {"wildcard": {"name": "*bob*"}}, {"wildcard": {"name": "*smith*"}} ] } } }
方案2:匹配不分词的keyword类型子字段
如果你的name字段有默认生成的keyword子字段(不分词,存储完整原始文本),可以直接针对该字段做wildcard查询,同时可以开启大小写不敏感配置适配大小写问题:
GET people/_search { "query": { "wildcard": { "name.keyword": { "value": "*bob* *smith*", "case_insensitive": true } } } }
方案3(更推荐,性能更高):使用match查询替代wildcard
通配符查询尤其是前缀带*的查询性能极低,数据量大时会严重影响查询效率,如果只是需要同时匹配两个关键词,直接使用match查询配置operator: and即可,天然适配分词逻辑:
GET people/_search { "query": { "match": { "name": { "query": "bob smith", "operator": "and" } } } }
内容的提问来源于stack exchange,提问作者dar25
相关产品推荐
相关产品推荐

