如何用Lucene查询含@、#特殊字符的Elasticsearch索引
问题:Elasticsearch中精确匹配含#/@前缀的特殊字符串
需要在Elasticsearch的comments字段中查询带@、#前缀的字符串(如@company.com或#rescheduled),要求仅匹配带前缀的完整内容,不能返回仅包含rescheduled的文档。尝试了多种查询语句均无效,Lucene文档显示#、@无需转义,但查询结果仍同时返回两种文档,无报错。
试过的查询语句:
comments:#rescheduled comments:"#rescheduled" comments:\#rescheduled comments:\"#rescheduled\" comments:\"\#rescheduled\"
解决方案
问题出在字段的分词逻辑上:默认的standard分词器会把#、@这类符号当成分词分隔符,导致#rescheduled被拆分为#和rescheduled两个独立词条,所以无论怎么写查询,都会匹配到含rescheduled的文档。
以下是两种可靠的解决方式:
添加keyword类型子字段(推荐)
给comments字段新增一个keyword类型的子字段(不影响原字段的分词查询能力),映射示例:{ "mappings": { "properties": { "comments": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } }之后用该子字段做精确查询:
comments.keyword:"#rescheduled"修改原字段为keyword类型(仅当不需要分词搜索时用)
如果comments字段不需要做分词模糊搜索,可以直接将其类型改为keyword,映射示例:{ "mappings": { "properties": { "comments": { "type": "keyword" } } } }此时直接用原字段查询即可:
comments:"#rescheduled"临时应急方案(无需修改映射)
若无法修改索引映射,可尝试使用match_phrase短语查询,强制匹配完整的短语序列:{ "query": { "match_phrase": { "comments": "#rescheduled" } } }注意:这种方式依赖分词后的词条顺序,稳定性不如keyword字段。
内容的提问来源于stack exchange,提问作者TripToBelize
相关产品推荐
相关产品推荐

