先上两个学习链接:
Elasticsearch API查询_森四杨的博客-优快云博客
1. es
分布式集群
1. 搭建过程
2. 概念
- 节点、分片(
Shards
)、副本(Replicas
)、索引、文档、字段、映射 - 对索引中的文档可以进行索引(插入)、搜索、更新和删除
2. 系统架构
3. 分布式集群
- 单集群节点、故障转移、水平扩容、应对故障
- 扩容的分配原则:1. 主副本不能在一个节点; 2. 每个节点负载均衡
- 主片的数目创建时就确定,后期只能修改副本的数目
- 颜色:green表示一切正常,yellow表示全部主片正常运行,副本分片没有全部处在正常状态。
- 应对故障时,主节点和主分片可能会改变。
3. 路由计算
-
索引一个文档(向索引中添加一个文档)时,需要计算放在哪个主节点上,使用公式:
主分片=hash(id)%主分片数目
- id是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。
4. 分片控制
- 索引文档、读文档、更新文档 (寻找文档,使用的是路由计算)
- 多文档操作
2. 倒排索引与实时搜索
1.倒排索引
- 分词器:
keyword:不能分词
text:可以分词
ik_max_word
: 最细粒度分词
ik_smart
:粗粒度分词
词条:索引中最小的存储和查询的单元
词典:字典,词条的集合,B+,HashMap
倒排索引
// 倒排索引过程:
if(词典.contains(target))
{ 1.倒排索引中寻找target的文档id;
2.寻找对应id的内容;}
else{结束}
2.文档搜索
- 倒排索引写入磁盘不可改变: 它永远不会修改。
- 索引更新(保留不变性下进行倒排索引更新):
- 增:补充索引,最后结果合并
- 删:先标记为删除,最后搜索结果将其过滤;之后合并索引时进行删除。
- 更新:旧的先标记,最后在结果集返回前将旧的给删除,保留新的
3. 近实时搜索
-
OS缓存区提供搜索,translog保证数据不丢失,索引时会自动合并段。
3. 文档分析器:分词+标准化
- 字符过滤器(
char_filter
):在分词前整理字符串 - 分词器(
tokenizer
):把字符串分为单个的词条。 - 过滤器(
token_filter
):改变、删除、增加词条
1.内置分析器
标准分析器、简单分析器、空格分析器、语言分析器
2.使用场景
- 当你查询一个 全文 域时, 会对查询字符串应用相同的分析器,以产生正确的搜索词条列表。
- 当你查询一个 精确值 域时,不会分析查询字符串,而是搜索你指定的精确值
3. IK分词器之IK中文分词器
ik_max_word
:会将文本做最细粒度的拆分ik_smart
:会将文本做最粗粒度的拆分- 专有名词设置
4. 自定义分析器
-
字符过滤器:
html_strip
、mapping
、pattern_replace
(正则替换) -
分词器:标准分词器(
standard
)、空格分词器(whitespace
)、正则分词器(pattern
)…… -
词单元过滤器: lowercase 、 stop 词过滤器、词干过滤器……
Elasticsearch内置分词器及字符过滤器 | 问问苑大宝 (yuanwenjian.github.io)
Elasticsearch内置分析器 | 问问苑大宝 (yuanwenjian.github.io)
Elasticsearch内置过滤器 | 问问苑大宝 (yuanwenjian.github.io)
// 自定义分析器 { "settings": { "analysis": { "char_filter": { "&_to_and": { "type": "mapping", "mappings": [ "&=> and "] }}, "filter": { "my_stopwords": { "type": "stop", "stopwords": [ "the", "a" ] }}, "analyzer": { "my_analyzer": { //自定义一个名为my_analyzer的分析器:字符过滤器,分词器,过滤器。type自定义分析器名称 "type": "custom", "char_filter": [ "html_strip", "&_to_and" ], "tokenizer": "standard", "filter": [ "lowercase", "my_stopwords" ] }} }}}
4. 文档冲突
1.悲观并发控制VS 乐观并发控制
- 文档冲突:多个线程并发修改文档数据,造成的数据不一致
- 悲观并发控制:阻塞访问资源以防止冲突,比如使用锁
- 乐观并发控制:假定冲突是不可能发生的,不会阻塞正在尝试的操作,但是源数据在读写当中被修改,更新失败。重新更新
2. 内部版本控制
- Elasticsearch 是分布式的。当文档创建、更新或删除时, 新版本的文档必须复制到集群中的其他节点。Elasticsearch 也是异步和并发的,这意味着这些复制请求被并行发送,并且到达目的地时也许 顺序是乱的。
- 需要一种方法确保文档的旧版本不会覆盖新的版本。
- 使用文档的 _version(旧版本)或者使用if_seq_no和 if_primary_term (新版本)
- _version要等于当前版本,if_seq_no和 if_primary_term要和当前的相同
3.外部版本信息
- 使用其它数据库作为主要的数据存储,使用 Elasticsearch 做数据检索, 这意味着主数据库的所有更改发生时都需要被复制到 Elasticsearch ,如果多个进程负责这一数据同步,你可能遇到类似于之前描述的并发问题。
- 可以在 Elasticsearch 中通过增加
version_type=external
到查询字符串的方式 - 对于外部版本号:Elasticsearch 不是检查当前 _version 和请求中指定的版本号是否相同, 而是检查当前 _version 是否 小于 指定的版本号。 如果请求成功,外部的版本号作为文档的新 _version 进行存储。
http://127.0.0.1:9200/shopping/_doc/1000?version=12&version_type=external
当前的版本号小于12则_version改为12