Elasticsearch中在text字段使用term级查询的相关疑问
Term级查询在text字段的行为疑问
索引结构(使用standard analyzer)
{ "my-index-000001" : { "mappings" : { "properties" : { "city" : { "type" : "text", "fields" : { "raw" : { "type" : "keyword" } } } } } } }
索引中的现有数据
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 2, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "my-index-000001", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : { "city" : "New York" } }, { "_index" : "my-index-000001", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : { "city" : "York" } } ] } }
测试查询及结果
执行以下wildcard查询:
GET my-index-000001/_search { "from":0,"size":20,"timeout":"20s", "query": { "wildcard": { "city": { "value": "yor*" } } } }
结果会匹配索引中的两个文档,且查询词大小写不敏感(比如yOR*也能匹配)。但如果将查询字段改为keyword类型的city.raw,则无匹配结果。
问题核心
官方文档说明term级查询不会分析搜索词,但在text字段上的表现似乎与此不符,请问这是预期行为还是bug?在text字段使用term查询是否安全?若不安全,原因是什么?
解答
这是预期行为,并非bug,核心原因是字段索引行为与查询行为的独立性:
- text字段的索引处理:text字段在索引阶段会被指定的分析器(这里是standard)处理——拆分词汇、转换为小写。所以"New York"会被拆成
new和york两个小写词存入倒排索引,"York"则被转为york。 - term级查询的匹配逻辑:term级查询(包括wildcard)确实不会分析搜索词,但它是直接匹配text字段已经处理好的索引词。当用
yor*查询时,匹配的是索引里的小写york,因此大小写不敏感,能命中结果;而city.raw是keyword类型,索引阶段保留原始字符串的大小写与格式,yor*无法匹配原始的"York",所以无结果。
不推荐在text字段使用term级查询,原因如下:
- text字段的索引内容是经过分析后的词汇,与原始输入差异较大,容易出现预期外的结果。比如直接用term查询"York"(大写),会匹配不到任何文档,因为索引里只有小写的
york。 - 若针对text字段做全文检索,应使用match类查询——这类查询会自动用与索引阶段相同的分析器处理搜索词,匹配结果更符合预期;若需要精准匹配原始内容,应使用对应的keyword子字段(如
city.raw)配合term级查询。
内容的提问来源于stack exchange,提问作者user1934513
相关产品推荐
相关产品推荐

