Elasticsearch自定义IP分析器搜索异常求助:匹配IP及含IP文本
问题分析与解决方案
首先咱们得搞清楚为啥你的查询没返回预期结果:你的自定义IP分词器my_custom_ip_analyzer的作用是只提取字段中符合IP格式的内容作为分词结果,其他非IP的文本会被直接忽略。比如第二个文档的IP_address字段值this is ip 192.168.1.1,经过分词后,倒排索引里只会留下192.168.1.1这个token,而不是整个字符串。你用term查询完整字符串是做精确token匹配,自然找不到对应结果。
针对你「搜索this is ip 192.168.1.1或192.168.1.1都能得到对应1条结果」的需求,给你两种调整方案:
方案1:使用match查询(推荐)
match查询会先对查询词应用你配置的my_custom_ip_analyzer做分词,自动提取出IP后再去倒排索引匹配,不管你输入的是带额外文本的字符串还是纯IP,都能匹配到目标文档:
GET /my_index/reports/_search { "query": { "match": { "IP_address": "this is ip 192.168.1.1" } } }
如果要直接搜索IP,用这个查询:
GET /my_index/reports/_search { "query": { "match": { "IP_address": "192.168.1.1" } } }
如果需要每个查询仅返回对应1条结果,可以在查询里加上document_id的过滤条件,比如搜索纯IP时只返回文档5:
GET /my_index/reports/_search { "query": { "bool": { "must": [ {"match": {"IP_address": "192.168.1.1"}} ], "filter": [ {"term": {"document_id": "Doc-4004-05-15"}} ] } } }
方案2:调整字段映射,支持精确匹配原始文本
如果你需要同时支持精确匹配整个原始字符串和IP搜索,可以修改字段映射,添加一个keyword类型的子字段来保存原始值:
PUT /my_index/_mapping/reports { "properties": { "IP_address": { "type": "text", "analyzer": "my_custom_ip_analyzer", "fields": { "raw": { "type": "keyword" } } } } }
修改映射后需要重新导入数据,之后就能用term查询原始字符串了:
GET /my_index/reports/_search { "query": { "constant_score": { "filter": { "term": { "IP_address.raw": "this is ip 192.168.1.1" } } } } }
同时依然可以用match查询IP值。
另外补充个小细节:你插入第二个文档的语句有语法错误,title字段后面少了逗号,修正后的语句应该是:
PUT /my_index/reports/6 { "document_id": "Doc-4006-06-16", "title": "logical", "IP_address": "this is ip 192.168.1.1", "rating": "low" }
内容的提问来源于stack exchange,提问作者vishal kumar




