一、小数点间的单词无匹配结果
场景
假设创建一个索引 test ,其中有这样一条数据:
POST /test/doc/1
{
"message": "13-Aug-2019 22:20:57.025 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 97207 ms"
}
我们通过关键词 apache
去搜索,发现结果并无法查询到这条 message :
GET /test/_search
{
"query": {
"match" : {
"message" : "apache"
}
}
}
---result---
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
产生原因
产生上述结果的原因是 ES 默认的分词器不会以小数点 .
作为分词依据, 则 org.apache.catalina.startup.Catalina.start
被认为一个 term ,使用 apache
查询时就无法进行匹配。
解决方法
在创建索引时给指定字段配置支持小数点分词的分词器,这里推荐 ik 分词器,ik 分词器的安装请参考其它教程,以下是具体配置:
PUT /test
{
"mappings": {
"doc": {
"properties": {
"message": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
二、wildcard模糊查询无匹配结果
场景
假设创建一个索引 test ,以下是相关配置和数据:
PUT /test
{
"mappings": {
"doc": {
"properties": {
"message": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
POST /test/doc/1
{
"message": "这是一条信息"
}
我们通过关键词 信息
去搜索,能查询到结果,但使用关键词 一条信息
却发现结果并无法查询到这条 message :
GET /test/_search
{
"query": {
"wildcard": {
"message": "*信息*"
}
}
}
---result---
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.0,
"hits": [
{
"_index": "test",
"_type": "doc",
"_id": "1",
"_score": 1.0,
"_source": {
"message": "这是一条信息"
}
}
]
}
}
GET /test/_search
{
"query": {
"wildcard": {
"message": "*一条信息*"
}
}
}
---result---
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
产生原因
message 插入索引时使用了分词,但 wildcard 查询时不会将查询关键词进行分词操作,导致无法匹配。
解决方法
想要实现类似数据库 like 的模糊查询,可以结合 keyword 类型进行全字段的匹配,查询语句如下所示:
GET /test/_search
{
"query": {
"wildcard": {
"message.keyword": "*一条信息*"
}
}
}
---result---
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.0,
"hits": [
{
"_index": "test",
"_type": "doc",
"_id": "1",
"_score": 1.0,
"_source": {
"message": "这是一条信息"
}
}
]
}
}
三、wildcard模糊查询大小写敏感
在上述结合 keyword 进行查询的基础上,发现查询是区分大小写的,想要忽略大小写进行模糊查询的话,在创建索引时可使用以下配置:
PUT /test
{
"settings": {
"index": {
"analysis": {
"normalizer": {
"keyword_lowercase": {
"filter": [
"lowercase"
],
"type": "custom"
}
}
}
}
},
"mappings": {
"doc": {
"properties": {
"message": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256,
"normalizer": "keyword_lowercase"
}
}
}
}
}
}
}