ElasticSearch查询实践与优化

1、背景

近期项目组需要对机器人服务进行升级改造,需要基于用户的信息匹配不同的机器人和评论文案。需求可抽象为:每个用户有n个标签,每个机器人有m个标签,每条评论文案有q个标签,需要为每个用户找到前k个最匹配的机器人和评论文案。

2、方案

机器人的量级在100w左右,评论文案的量级在1w条左右,机器人和评论文案都存在多个标签。刚开始我们想基于map来给每个用户匹配机器人和评论文案:把每种标签对应的机器人和评论文案都存储在map中,业务侧根据用户标签实时查询每种标签对应的机器人和评论文案。这种方案主要的缺点是扩展性较差且浪费存储,当key为不同的标签时,相同的机器人和评论文案需要存储多次;同时map只能根据key实现精确查找,无法实现模糊匹配或者根据某种条件对机器人和文案进行过滤。

根据机器人的标签、评论文案的标签和用户信息来进行匹配其实跟搜索引擎里面输入关键词跳出相关性最高的结果很类似,同时考虑到实时性,我们采用es来实现为每个用户找到前k个最为匹配的机器人和评论文案的需求,qps约为5200。

3、查询方式1.0:match+wildcard

首先新建robot 的索引,然后我们把每个机器人的信息(包括出生日期YYYY年MM月DD日、地域以及标签等)保存在不同doc中,此处这些信息都是string类型的字段。

es中有两种查询模式,一种是像传递URL参数一样去传递查询语句,比如下面这条查询语句可以查询robot这个索引中的所有文档且返回结果按照json格式打印

curl "http://9.25.176.228:8080/robot/_search?q=*&pretty"

另外一种是通过DSL语句来进行查询,被称为DSL查询(Query DSL),DSL是Elasticsearch提供的一种丰富且灵活的查询语言,该语言以json请求体的形式出现,通过restful请求与Elasticsearch进行交互。上面的查询语句可以等价为:

curl http://9.25.176.228:8080/robot/_search?pretty -H 'content-type:application/json' -d '{"query":{"match_all":{}}}'

 这两种方式的查询的结果是一样的。

3.1、match query

match查询会先对搜索词进行分词,分词完毕后再逐个对分词结果进行精确匹配,因此match实现的是分词匹配搜索,需要注意的是Elasticsearch中默认的标准分词器在处理中文的时候会把中文单词切分成一个一个的汉字来进行匹配。例如某些文档中机器人的标签是“机器人身份-粉丝”,还有一些文档中机器人的标签就是“粉丝”,那么输入“机器人身份-粉丝”,就可以匹配上所有标签中含有“机”、“器”、“人”、“身”、“份”、“-”、“粉”和“丝”这几个字当中任何一个字的文档,并且匹配的字越多,打分越高,该文档越靠前。

使用match query需要确保该字段是分词的,创建doc的时候字符串类型默认就是“text”格式,支持分词。

 

3.2、wildcard

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值