Alpha版本接触到的ES issues
keyword
- 一定是要全词匹配,大小写匹配,否侧使用match不返回
- ** 如果text更好,那么什么时候需要直接定义字段为keyword,最佳实践
- 可枚举的字符串常量,并且该字符串常量不用来做搜索使用,例如status=published/draft
- uuid、isbn等,不太可能进行搜索的字符串
- email addresses, hostnames, status codes, zip codes or tags,可能做也可能不做搜索,即使做搜索也可能用text+keyword的mapping
- 并没有特定的场景,非要定义成keyword不成,有也是比较少有的例子,如果用了keyword还不一定能变回来text,干脆都使用text算了
- 部分数字类型的数据也可以map成keyword,如果该数字类型不需要用来做范围比较等,例如ISBN号,https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html
- ** keyword搜索使用term还是match
- match能处理text、boolean、number常用类型的数据
- match也能搜索keyword,但是match搜索时会经过token处理,可能在搜索速度上和term的相比会更慢
- term有一个问题是本身不支持fuzziness,要使用term的fuzzy query,但是官方建议不要用而是用match,这样不如使用match更加统一
- 可以先按照官方的定义先用term对keyword使用,也可以全都统一使用match,后续进行性能比较;如果统一都用text,则没有term的使用场景了
text
- 使用match匹配并非是一定都会返回结果,有相关性时才会返回
- 如果是子词,不一定会返回,例如Market不会返回Marketing的数据,需要用模糊查询
- 把text创建keyword的index,https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html
- 一般用来做sort、aggs的操作,目测比较适用于短词语,如果是长句子没有必要创建keyword的index
- 除了rich text和multiple line text的类型不需要index成keyword,其他text都需要index成keyword
- ?appbase.io用到了好几种analyzer(autosuggest_analyzer、english_analyzer、ngram_analyzer),怎样使用analyzer
- cms数据类型相关,http://wiki.inceptionpad.cn/4-projects/gig-economy/pg-related/cms-support-data-type.html
- text类型index处理
- single line text -> text + keyword
- ?rich text/html -> text
- select -> text + keyword
- multi-select -> text + keyword
- radio -> text + keyword
- checkbox -> text + keyword
- json -> object + auto
- text类型index处理
- ?枚举类型处理
- 原则上枚举类型应该支持几种基础类型:text、integer、float、date、time、datetime;目前只取text为了方便,没有value/text的pair option存储
- 缺点:修改option text时的操作麻烦
- 允许修改旧值,但是已经使用旧值的数据需要逐个手动迁移
- 不允许修改旧值,只允许新增,如果旧值要迁移,则要手动逐个进行迁移
- 允许修改值,后台把历史值全部变成新值,并且同步es
- 缺点:修改option text时的操作麻烦
- pg创建一张额外的表+关联的方式来操作,有部分cms根本不支持select/checkbox类型的数据,为的就是分开表存储更好表示数据结构
- 缺点:多对多结构同步nested数据时需要多一层,需要减少层的话则需要额外进行处理
- 原则上枚举类型应该支持几种基础类型:text、integer、float、date、time、datetime;目前只取text为了方便,没有value/text的pair option存储
- 一般用来做sort、aggs的操作,目测比较适用于短词语,如果是长句子没有必要创建keyword的index
match
- fuzzy的配置https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html#query-dsl-match-query-fuzziness
- 一般是用来做text类型的全文匹配,但是可以用来匹配keyword、number、boolean,就是直接匹配的场景了
multi_match
- index成多个field的查询使用场景,https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#type-most-fields
bool query
- https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html,4种方法相互补充使用,可是使得最后的score计算值和想要得到的搜索结果吻合
- ?实现嵌套条件的搜索
- 在migrate上使用,每一级都可以套bool作为subquery
- query dsl的可视化工具使用,migrate
- 使用门槛有点太高,基本对标了官方dsl,不太适合作为c端产品使用
- must vs should
- https://stackoverflow.com/questions/28768277/elasticsearch-difference-between-must-and-should-bool-query
- 经过测试,如果query里面只有should没有must,should会把score=0的结果也包含在内部,需要加参数才能把这些score=0的过滤掉,https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html#bool-min-should-match;在目前语句中,最外层用了must,就解决这个问题了
term
sort
- The order defaults to desc when sorting on the _score, and defaults to asc when sorting on anything else,https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-sort
- text类型的不能进行sort,会直接报错,只能把text类型的数据index一个fields是keyword类型的数据,https://stackoverflow.com/questions/49672496/how-to-sort-on-field-type-text-in-elastic-search
- ?使用sdk时发现sort的对象形式的写法不支持,需要查一下,https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#_search
- ?使用painless动态计算排序,https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-sort-context.html
boost
- 针对字段(multi-match)或者查询语句的boost,相关api
- https://www.elastic.co/guide/en/elasticsearch/reference/current/compound-queries.html
- https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-boost.html#mapping-boost
- https://www.elastic.co/guide/en/elasticsearch/reference/7.5/query-dsl-term-query.html
- https://www.elastic.co/guide/en/elasticsearch/reference/7.5/query-dsl-multi-match-query.html
score
- https://www.elastic.co/guide/en/elasticsearch/reference/7.5/query-filter-context.html#relevance-scores
- https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-intro.html#
- https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html
fuzzy/fuzziness
使用模糊匹配是要注意,查询的fields的数据类型,keyword类型是根据编辑距离进行匹配。 而复杂类型比如text类型会先进行分词,提取词根,和删除停用词,再根据提供的编辑进行匹配,所以效果并不是直接客观的。 如果是做suggest 或auto completion,es有专卖的类型和查询方式。 如果是拼写纠错类的类似于Name,Location等数据的模糊查询,推荐使用string类型或者上面说的es自带suggester 或者要一定要进行text类型的fuzzy query的话根据情况使用其它类型的analyzer改变文本解析行为。
如果要使用fuzziness的话,最大支持的编辑距离为2,一般设置为auto 就好了 参数有0,1,2 手动表示要设置支持的最大编辑距离。 AUTO:根据term长度自动设置编辑距离长度 tip:该值,可以设置1.5等非整数,或者大于2的整数,虽然不会报错,但是没有意义, 小数会向下取整,大于2的视为2
- https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html#query-dsl-match-query-fuzziness
- https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html
- learn
- https://qbox.io/blog/elasticsearch-optimization-fuzziness-performance
- fuzziness=auto+prefix_length=3足够使用,prefix_length越大性能越高,prefix_length表示不能忽略匹配的前缀单词个数,如果是3,表示头3个字符必须完全匹配,如果不匹配,就没有后续的模糊搜索
- https://codingexplained.com/coding/elasticsearch/fuzzy-searches
- https://www.elastic.co/blog/found-fuzzy-search
- 官方建议不要使用fuzzy query,因为match的功能和此类似,使用fuzzy query会增加理解成本
- https://qbox.io/blog/elasticsearch-optimization-fuzziness-performance
wildcard
array
geo
?special query
- https://www.elastic.co/guide/en/elasticsearch/reference/current/specialized-queries.html
- script,https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html,可以用来做函数式的自定义搜索
?aggs
- ?只能在term上用keyword类型进行聚合,试了一下text类型的无法聚合
?query_string
- https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
- vs dsl
- 不支持nested数据
- 直接支持嵌套条件查询,应该可以转成dsl的语法
?script
autosuggest
es 针对autosuggest 有专门的数据类型和查询方式 简明教程
https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-search.html
- https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-suggesters.html