倒排索引
以前是id对应数据
1001 hello Myworld
倒排是
hello 1001
world 1001
分词器主要对hello Myworld做分词
还要看hello Myworld得数据类型,如果是keyword就无法分词就是
hello Myworld 1001
分词器得话主要是ik_max_word最细粒度区分和ik_smart区分
词条:索引中最小存储和查询单元
词典:字典,词条的集合,B+tree,hashMap
倒排表:单词在倒排列表中的存储位置
理解倒排表:
假设我们爬取了4个文档,里面的内容如下
基于4个文档,写出我们的词库 [我们,今天,运动,昨天,上,课,什么]
统计词库中的每个单词出现在哪些文档中,显然 我们 出现在[doc1,doc2] 中
这样我们就可以把文档以到排表的方式存储了,这样做有什么优点呢???
假如用户输入:我们 上课
如果没有到排表,则只能一篇一篇的去搜索文档中 是否既包含我们又包含上课,这样复杂度太高了
有了到排表:我们知道 我们[Doc1, Doc2], 上 [ Doc3,Doc4], 课[Doc3,Doc4], 如果有交集,我们可以直接返回交集,如果没有交集,那么直接返回
并集[ Doc1,Doc2, Doc3,Doc4]
索引的修改
修改的流程:
首先索引会到内存中,做分段处理——形成dao’pian
其实并不是修改,只是增加了一个新的索引,以前的索引实际上只是在 .del 文件中被 标记 删除。查询的时候能查询到,只是返回给你的时候过滤掉了。
什么时候删除掉呢?
当倒排索引(段)合并的时候,按照上述的规则,才开始删除掉这个被.del文件标记的索引。
近实时搜索
es大致流程一个索引过来,先到主节点根据分片的路由计算查询到这个索引存储在哪个位置
然后开始写入数据到主节点,写完后根据副本数量开始并行写数据到多个副本中。
es数据更新的时间主要为:
主分片数据写入的时间+(并行写入)副本的最大延迟时间
每个(节点)分片数据写入到磁盘中大致流程
总结一下,数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache(操作系统缓存),到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。
注意:每秒刷新到os cache中的就是一个段(倒排索引),段也可以合并,并且会消耗 I/O 和 CPU资源,那些被删除的文档会在段合并的时候删除掉,合并成一个大段后30分钟默认刷新到磁盘。
你可以配置refresh_interval修改刷新到oscache的频率,比如日志,不需要每秒刷新,可以使用。
或者建立大的索引时,可以先关闭refresh_interval设置-1,好了后在开启。
分词器
es只对英文做一些分词,中文的话只会分割成一个个,所以需要ik分词器,
相当于插件,解压方法plugins目录下
# GET http://localhost:9200/_analyze
{
"text":"测试单词",
"analyzer":"ik_max_word"
}
自定义分词
首先进入 ES 根目录中的 plugins 文件夹下的 ik 文件夹,进入 config 目录,创建 custom.dic文件,写入你要自定义的分词例如弗雷尔卓德。同时打开 IKAnalyzer.cfg.xml 文件,将新建的 custom.dic 配置其中,重启 ES 服务器。
自定义分析器
为什么要自定义呢?
比如html中有的

# GET http://127.0.0.1:9200/my_index/_analyze
{
"text":"The quick & brown fox",
"analyzer": "my_analyzer"
}
文档处理
文档冲突
比如两个用户同时修改一个索引的时候,首先都获取全部的索引,都提交,这样的话最后一个提交的人将覆盖前面一个提交人的数据,这里会有问题。
并发乐观锁。
根据版本号来控制
post修改请求后加?if_seq_no=最新版本号&if_primary_term=最新版本号
系统会判断是不是最新版本号,不是的话会报错。
外部版本号?
什么意思呢,一般公司用mysql或者orcl作为主要数据库,用es作为搜索数据库,数据更新后主要数据库更新了,主数据库也更新,不过可能存在多个进程同时运行,这也会造成上述的文档冲突问题,所以这里有个外部版本的控制post更新后增加?version=大于当前外部版本号的值&version_type=external