仅供自己记录使用,不做知道
ES查询踩坑
- 前言
- 一、背景和问题描述
- 二、排查过程
- 1.ES-mapping创建
- 2.数据查询
- 问题解决
- 结论
前言
本文主要是记录在使用ES过程中中文查词的那些坑
一、背景和问题描述
要求:需要使用ES查询一段长文本,改文本中的一定的词语比例出现在doc中,该doc的内容就需要被查出
结果:使用ik_smart中文分词器分词后系统无法匹配出哪怕是100%相同的结果
二、排查过程
1.ES-mapping创建
1.创建indice PUT indice_example
2.创建对应的type和mapping
POST /indice_example/type_1/_mapping
{ "title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 5000
}
}
}
}
3.插入数据(此处只是举例说明)
PUT //indice_example/type_1/_id:0001
{"title":"支持公共福利事业,设立100个左右的消防栓"}
2.数据查询
由于是基于文字匹配且需要分词,此处我们使用MATCH作为查询方式,结合bool查询匹配更多条件,后续会单独出文章简述不同的查询方式以及其所使用的场景:
GET /indice_example/type_1/_search
{
"query": {
"bool": {
"must": [{
"match": {
"title": {
"query": "支持公共福利事业,设立100个",
"operator": "or",
"analyzer": "ik_smart",
"prefix_length": 0,
"max_expansions": 50,
"minimum_should_match": "80%",
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}]
}
}
}
此处查询结果为空,做了诸多查询,都无效
注意,此处有一个参数为 minimum_should_match,此参数较为重要
比如 “minimum_should_match”:3 ,原文解释是:Indicates a fixed value regardless of the number of optional clauses.
这里要说明一下为什么是optional clauses(翻译为可选的子句)
对于minimum_should_match设置值:
1.minimum_should_match:“3”
无论可选子句的数量如何,都表示固定值.
2.minimum_should_match:“-2”
表示可选子句的总数减去此数字应该是必需的。
3.minimum_should_match:“75%”
表示最少匹配的子句个数,例如有五个可选子句,最少的匹配个数为5*75%=3.75.向下取整为3,这就表示五个子句最少要匹配其中三个才能查到.
4.minimum_should_match:“-25%”
和上面的类似,只是计算方式不一样,假如也是五个子句,5*25%=1.25,向下取整为1,5最少匹配个数为5-1=4.
5.minimum_should_match:“3<90%”
表示如果可选子句的数量等于(或小于)设置的值,则它们都是必需的,但如果它大于设置的值,则适用规范。在这个例子中:如果有1到3个子句,则它们都是必需的,但是对于4个或更多子句,只需要90%的匹配度.
GET /indice_example/type_1/_search
{
"query": {
"bool": {
"must": [{
"match": {
"title": {
"query": "支持公共福利事业,设立100个",
"operator": "or",
"analyzer": "standard",
"prefix_length": 0,
"max_expansions": 50,
"minimum_should_match": "80%",
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}]
}
}
}
此时有数据
问题解决
ES在type为text创建和数据写入是会针对写入的文本开始分词,分词结束后创建倒排索引存储
如果不指定分词器,ES会使用默认的分词器 standard处理,standard针对中文是单个字单个字的分词
在查询过程中,如果未指定分词器,使用的也会是standard的(其实如果此处不写,ES会默认的使用Mapping创建锁设置的分词器)
如果重新指定了分词器,会导致分词后无法命中
结论
在ES做中文类查询时,如果需要特定的分词策略,要求此时在Mapping创建阶段就指定出来,否则后续会造成分词不统一无法命中的
并且,一点mapping创建了,也无法去修改分词器,此处需要慎重对待