ElasticSearch
学习进度
看到这里了:https://www.elastic.co/guide/cn/elasticsearch/guide/current/_preventing_combinatorial_explosions.html
笔记
Near Real Time
打分机制:从TF-IDF改成BM25,也叫similarity ,scoring,ranking
oversharding问题,如何创建分片数?
如何知道数据在集群中的哪个节点?
es和mysql数据模型区别?
结构化搜索和全文搜索
全文搜索:传统数据库确实很难搞定的任务,传统数据库要么匹配,要么不匹配,es有相关性打分。
PB级别,数百台服务器
一个分片是一个 Lucene 的实例,以及它本身就是一个完整的搜索引擎
每个字段的所有数据都是默认被索引的
index是逻辑概念,面向用户,shard是物理概念,面向机器,应用程序关心索引,而不是分片
Elasticsearch中文档是不可改变的,不能修改它们,在内部,Elasticsearch 已将旧文档标记为已删除,并增加一个全新的文档,并且会重新进行索引。
更新文档:标记删除,创建文档,重新索引,检索-修改-重建索引
文档中的每个字段都将被索引并且可以被查询
在分布式系统中深度分页:在分布式系统中,对结果排序的成本随分页的深度成指数上升
filed:精确值,全文值
很少对全文类型的域做精确匹配
Doc Values:排序,聚合,脚本计算 Invert Index:检索
文档的唯一性:index,type,routing value
检索过程:query then fetch 先查后取 分片节点:from+size 协调节点:numberOfShard * (from+size)
scroll 查询禁用排序
搜索类型:query then fetch,dfs_query_then_fetch
深度分页的代价根源是结果集全局排序,如果去掉全局排序的特性的话查询结果的成本就会很低。
Data Replication:Primary-Backup
in-sync shard(可以被选中为primary的shard)
index配置最重要的是:number_of_shards(创建后更改不了),number_of_replicas(创建后可以修改)
_id 和 _index 字段则既没有被索引也没有被存储,这意味着它们并不是真实存在的。
不能添加新的分析器或者对现有的字段做改动。 如果你那么做的话,结果就是那些已经被索引的数据就不正确, 搜索也不能正常工作。reindex
修改索引类型:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index-aliases.html
应用中使用索引别名,而不是索引真实名字。这样在修改索引时候,应用层不需要变化。
全文检索=全字段索引
倒排索引被写入磁盘后是 不可改变 的 在保留不变性的前提下实现倒排索引的更新?答案是: 用更多的索引。
一个 Lucene 索引包含一个提交点和三个段
一个 Lucene 索引 我们在 Elasticsearch 称作 分片 。 一个 Elasticsearch 索引 是分片的集合
段是不可改变的
内存索引缓冲区
按段搜索
写入和打开一个新段的轻量的过程叫做 refresh,每1s refresh下
Elasticsearch是近实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见
Flush:执行一个提交并且截断 translog 的行为在 Elasticsearch 被称作一次 flush,30分钟一次。 Flush之后段被全量提交,并且事务日志被清空
减少段的数量(通常减少到一个),来提升搜索性能。
结构化搜索:要么在,要么不在,和打分机制无关系。也就是和相似度无关。
精确值查找时候,需要用filter,不会被打分,会被缓存。
尽可能多的使用过滤式查询。
constant_score(常量评分查询) 将 term 查询转化成为过滤器。
term查询转成constant_score查询。(非评分查询)
非评分计算是首先执行的,这将有助于写出高效又快速的搜索请求。
bool过滤器,也叫复合过滤器。
查看索引别名:GET /finance_netease_settle_order/_alias
布尔过滤器可以用来作为构造复杂逻辑条件的基本构建模块。
term 和 terms 是 包含(contains) 操作,而非 等值(equals)
查询优化:普通查询 -> bool filter -> constant_score filter
exists(!=null),missing(==null)查询
filter query 实现bitset的roraing bitmap
bool match查询
多数字符串字段都是 not_analyzed 精确值字段
dfs_query_then_fetch: dfs是指分布式频率搜索(Distributed Frequency Search) , 它告诉 Elasticsearch , 先分别获得每个分片本地的 IDF ,然后根据结果再计算整个索引的全局 IDF 。
多字段搜索:bool match查询
dis_max:分离最大化查询(Disjunction Max Query)
全文搜索被称作是 召回率(Recall) 与 精确率(Precision) 的战场 召回率 ——返回所有的相关文档; 精确率 ——不返回无关文档
TF/IDF
字段中心式(term-centric)查询:best_fields 和 most_fields 词中心式(term-centric)的查询:cross_fields
自定义单字段查询是否能够优于多字段查询,取决于在多字段查询与单字段自定义 _all 之间代价的权衡, 即哪种解决方案会带来更大的性能优化就选择哪一种。
multi_match 查询中避免使用 not_analyzed 字段。
短语匹配(match_phrase查询)
http://people.apache.org/~mikemccand/lucenebench/
unigrams ,bigrams(shingles),trigrams,
shingles 不仅比短语查询更灵活,而且性能也更好。 shingles 查询跟一个简单的 match 查询一样高效,而不用每次搜索花费短语查询的代价。
prefix 查询不做相关度评分计算,它只是将所有匹配的文档返回,并为每条结果赋予评分值 1 。它的行为更像是过滤器而不是查询。
search-as-you-type:match_phrase_prefix
Boolean Model:只是在查询中使用 AND 、 OR 和 NOT
Lucene 使用 布尔模型(Boolean model) 、 TF/IDF 以及 向量空间模型(vector space model) ,然后将它们组合到单个高效的包里以收集匹配文档并进行评分计算。
bool 查询实现了布尔模型
查询时的权重提升 是可以用来影响相关度的主要工具
constant_score 和 function_score区别?
一致随机评分(consistently random scoring)
similarity算法:BM25,TF-IDF
全文搜索是一场 查准率 与 查全率 之间的较量—查准率即尽量返回较少的无关文档,而查全率则尽量返回较多的相关文档。
es多字段,可对字段建立两次索引。文本做两次索引
stem 词干 stemmer 词干提取器
多语言设计:index-per-language, field-per-language
Elasticsearch 为什么不能在 analyzed (分析过)的字符串字段上排序,并演示了如何为同一个域创建 复数域索引 , 其中analyzed域用来搜索,not_analyzed域用来排序。
Analyzed 域无法排序并不是因为使用了分析器,而是因为分析器将字符串拆分成了很多词汇单元,就像一个 词汇袋 , 所以 Elasticsearch 不知道使用那一个词汇单元排序。
analyzed name域用来搜索。 not_analyzed name.raw 域用来排序。
International Components for Unicode (ICU)
单词还原成词根。比如foxes还原成fox.
Internals
https://www.elastic.co/blog/found-elasticsearch-internals https://www.elastic.co/blog/found-elasticsearch-networking
遇到问题
1.forbidden-12-index-read-only-allow-delete-api?
某个节点的磁盘满了,需要运维清理下磁盘
Course
https://github.com/xiaozhiliaoo/geektime-ELK
https://github.com/xiaozhiliaoo/search-practice