Elasticsearch | 检索问题记录

一、小数点间的单词无匹配结果

场景

假设创建一个索引 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"
                        }
                    }
                }
            }
        }
    }
}
上一篇:2021-01-16 打砖块


下一篇:打砖块