elasticsearch自定义分词器实现like模糊匹配查询,代替使用通配符模糊搜索慢的实现

前段时间第一次使用es实现全文检索功能,由于第一次使用,所以只想实现类似数据库 LIKE ‘%关键字%’这样的就可以了。

简单研究了一下es之后,发现将字段类型指定为keyword或查询字段加上.keyword,然后再通过*实例模糊匹配,如下面查询,就可以实现类似LIKE ‘%关键字%’的搜索。

GET /my_index/_doc/_search
{
	"query": {
		"query_string": {
			"query": "*关键字*",
			"fields": [
				"field1.keyword",
				"field2.keyword",
				"field3.keyword",
				"field4.keyword"
			]
		}
	}
}

虽然这样达到了想要的结果,但过了一段时间发现es这种查询有性能问题,如果关键字内容越长查询时间越长,例如查询10个字符的关键字,数据量才几w级别的竟然要4、5秒,还不如优化过的sql查询。

实现配置

elasticsearch 版本: 6.3.0

实现原理

将内容按字符分词,然后查询的时候也是按字符匹配,并且还要满足字符的顺序,如:

  • 内容:elasticsearch自定义分词器实现模糊搜索。
  • 分词后:e, l, a, s, t, i, c, s, e, a, r, c, h, 自, 定, 义, 分, 词, 器, 实, 现, 模, 糊, 搜, 索。
  • 搜索关系字:自定义分词器
    匹配“自, 定, 义, 分, 词, 器”这个几个字符,并且它们的位置满足:自<定<义<分<词<器,并且相邻两个字符位置差值都是1。

以上关键是最后一步,可以用 match_phrase 这个查询实现。

创建索引时创建自定义分词器
// 创建索引
PUT /my_index
{
 "settings": {
		"analysis": {
			"analyzer": {
				// 自定义分词器
				"char_analyzer": {
					// 使用自定义的token分词器
					"tokenizer": "char_tokenizer",
					// 转成小写,实现忽略大小写查询,如果需要区分大小写把下面的filter去掉
					"filter": "lowercase"
				}
			},
			"tokenizer": {
				// 定义一个token分词器,作用是将内容按字符拆分
				"char_tokenizer": {
					"type": "pattern",
					"pattern": "|"
				}
			}
		}
	}
}
使用分词器

使用分词器有两种方式,一种是使用动态模板给满足条件的字段指定分词器,另一种就是给指定的字段设置分词器,使用其它一种就好了。反正就是要给需要查询的字段使用上刚刚定义的分词器。

// 使用动态模板,指定自定义分词器
PUT my_index/_doc/_mapping
{
	"_doc": {
		"dynamic": true,
		"dynamic_templates": [{
			"my_analyze": {
				"match_mapping_type": "string",
				"mapping": {
					"analyzer": "char_analyzer"
				}
			}
		}]
	}
}

// 指定字段设置分词器
PUT my_index/_doc/_mapping
{
	"_doc": {
		"properties": [{
			"field1": {
				"analyzer": "char_analyzer"
			},
			"field2": {
				"analyzer": "char_analyzer"
			}
		}]
	}
}
关键部分,实例模糊查询

这是最关键的部分

GET /my_index/_doc/_search
{
	"query": {
		"query_string": {
			"query": "关键字",
			// [关键]作用:满足条件需要按顺序匹配关键字的每一个字
			"type": "phrase",
			// [关键]作用:需要匹配到每一个关键字
			"operator": "AND",
			// [关键]作用:跟上面一样,需要匹配到每一个关键字
			"minimum_should_match": "100%",
			"fields": [
				"field1",
				"field2",
				"field3",
				"field4"
			]
		}
	}
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值