最近在做商品评论的相关内容,因为数据量比较大,而且后台需要根据内容进行评论匹配的功能,显然用mysql 的 like 不太合适了,我们用的是elasticsearch。
需要注意的几个点:
- es 每条记录都有 id , 这个id 不等同于我们结构体中的id, 需要我们手动指定,如果我们不指定,es 会默认生成一个字符充当id, 当我们用get 请求的时候拼接的id 也是 此id (如果id 重复后插入的会覆盖之前的)
1 | { |
2.当我们想获取es 的版本号的时候我们可以发送 get / 请求,能获取到版本号
3.es 7 好像废弃了 type 的存在,之前我们可以理解 index 数据库,type 表
4.es 的那些搜索条件
1 | sort 和 query 是同一个级别的 |
5.我们在构造query 参数中需要注意的几个点
1 | query 第一层无可厚非 |
6.我们在用es 更新的时候不一定马上能刷新,比如删除,比如修改,我们可以用refresh = wait_for, 这个就相当于是同步的,默认是false 是异步的,如果用true 所有的都这样会影响性能。
关于刷新, 这篇文章讲的挺好的,其实wait_for 也不是马上刷新,只是加了wait for 之后那个接口会在等待刷新完成之后才返回结果。
7.es 的聚合功能,我们在口碑中有使用到这篇文章用法讲的很仔细
1 | // 必备的属性,不能缺少 |
8.es 搜索到的内容json转换成我们需要的内容
1 | if searchResult.TotalHits() > 0 { |
9.es 中经常遇到的mapping 问题 一般都是字段名字写错了, 而且 es 的mapping 设定好修改包括字段类型,就不方便修改了
10.es 中查询值不存在,试试
1 | { |
11.es 的遍历 。类似redis 的遍历, https://www.cnblogs.com/WalkOnMars/p/12377313.html, 注意不要用search_type=scan, 直接用
1 | GET /_search?scroll=1m // 这个1m 代表1min, 我再次请求中间的时间间隔,快照只会保留着在 1min |
search_type 这种方式早就下线了,上面的scroll 方式效率也很高,因为不排序。
12.es 想获取分片信息,直接 /shihuo_other_comment_dgscore?pretty, 能获取index 的详细信息,比如6个shard
13.桶聚合的数据其实是不准确的
原理看下这篇文章 :https://segmentfault.com/a/1190000022025890, 为了让更加准确,用一个shard 显然不合适,所以调大聚合的数据,比如 聚合的时候,termes 里面的size 我使用的是200, 让聚合更加准确
1 | 这两个很重要的指标 |
14.关于es 的更新操作,好久之前在写php 的时候就发现 create 和 update 功能一样,这次特地查了下,es 其实还是分不分更新和整体更新
部分更新 :https://www.elastic.co/guide/cn/elasticsearch/guide/current/partial-updates.html, _update 方法,如果没有查询到这个doc( 不同于update_by_query 用的id 索引), 就更新失败。
整体更新:https://www.elastic.co/guide/cn/elasticsearch/guide/current/update-doc.html#update-doc, 这种更新是那种如果不存在就插入,其实还蛮好用的。
注意上面两种方法参数有一些不一致。
15.今天在并发更新es 的时候出现错误,归其原因就是并发时候隔离性的问题 (es 控制并发用的乐观锁,每条数据都有个version 记录 ,mysql 也有,mysql 用mvcc 的事务隔离级别完美避开了 并发问题)
比如同时读取一条数据,同时 update, 到底用哪个
https://www.jianshu.com/p/7a3652bae8a4 。 es 更新数据的时候会比对 version, 如果version 不一致,就不能更新。但其实如果version 较大,也是可以更新的,用 &version_type=external 比如
1 | 1. version 1 , 1 ->2 |
es 如果对一个字段,重复更新,version 版本号不会改变。
一旦我们用了 &version_type=external, 我们doc 记录的version 就变成我们传入的version了,我没法控制每次version 的大小 递增(可不可以按照毫秒级别 ? 或者类似雪花算法的模式,一定要是递增模式,但这样还是可能存在覆盖问题,因为但凡带了机器的前缀 ,就会有个优先级)。 目前我最简单的方法就是重试。 这样看来,es 还不能当做数据库使用,同时修改的时候还是会存在并发问题。