前言:现在想要实现在elasticsearch中类似于mysql的like查询方式,有下面几种方法可以参考
建议:wildcard方法是纯纯的like查询方式平替,但是性能差,上百GB的数据量后就会很慢。根据自己业务量需求,前面两种方式能解决的情况下尽量用前面两种方式。前两种方式可以修改索引细粒度逐步靠近like查询效果。
一、match方式查询
1、前言:
- match方式是会将输入筛选的内容先分词,匹配库中的数据记录的分词内容,匹配成功则会返回。
- 这种方式由于使用到了分词,根据自己的数据量确定分词细粒度,如果想要贴近like,ngram分词器细粒度可设置成1
- 此查询适用于文本搜索场景,可以匹配文档中的任意一个词,但无法保证匹配的词语在文档中是相邻的
- 在匹配长文本时,匹配的结果可能会受到文本长度的影响,导致查询结果不准确
2、es查询命令
下面命令是筛选fileName中含有2010的记录
注意:由于match会分词后查询,所以fileName中含有2,0,1这些字符的记录也会返回
POST es_test/_search
{
"track_total_hits": true,
"size": 1000,
"query": {
"match": {
"fileName": "2010"
}
}
}
二、match_phrase方式查询
1、前言
- match_phrase查询是一种基于分词的短语匹配查询,它可以匹配多个关键字,并保证这些关键字在文档中是相邻的
- 此方式查询内容过长时效率会变慢,注意这方面的限制
- 输入的内容会被当做一个完整的短语进行匹配。比如输入的是2010,只会查询包含完整短语"2010"的文档。如果某个文档中包含了"2010年"或者"在2010年度"等,这些文档是无法被匹配出来的
2、es查询命令
下面命令是筛选fileName中后缀为.mp4的记录
POST es_test/_search
{
"track_total_hits": true,
"size": 1000,
"query": {
"match_phrase": {
"fileName": ".mp4"
}
}
}
三、wildcard方式查询
1、前言
- Wildcard查询是一种基于通配符的查询方式,通配符包括 *(匹配任意字符)和 ?(匹配单个字符)
- Wildcard查询性能相对较低,因为它会扫描整个索引来找到匹配的结果
2、es查询命令
此命令是查询fileName中包含mp4的记录
POST es_test/_search
{
"track_total_hits": true,
"size": 1000,
"query": {
"wildcard": {
"fileName": "*mp4*"
}
}
}
四、综合方式复杂查询
上面是单个查询方式的用法,如果显示更友好,可以下面方式优化
1、需求场景
现在想要实现如下需求,根据百度查询效果一样的,输入一个内容,完全匹配的排前面,部分匹配的排后面
2、思路
用match_phrase方式查询完全匹配的内容,用match查询部分匹配的内容,并分别加权
3、es查询命令
下面命令是fileName中完整包含2010字段的排前面,加权10,部分包含2010字段的排后面,加权5,es查询结果不sort的情况下默认会按分数排序
POST es_test/_search
{
"track_total_hits": true,
"size": 1000,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match_phrase": {
"fileName": "2010"
}
}
],
"boost": 10
}
},
{
"bool": {
"must": [
{
"match": {
"fileName": "2010"
}
}
],
"boost": 5
}
}
]
}
}
}
如果有其他建议或问题意见,欢迎留言交流!!!