深入理解ElasticSearch读书笔记

第2章 查询DSL进阶
2.1 Apache Lucene 默认评分公式解释
Lucene默认评分公式是如何工作的。
什么是查询重写。
查询二次评分是如何工作的如何在单次请求中实现批量准实时读取操作。
如何在单次请求中发送多个查询。
如何对包括嵌套文档和多值字段的数据排序
如何更新已索引的文档。
如何通过使用过滤器来优化查询。
如何在ElasticSearch的切面计算机制中使用过滤器和作用域

现在,让我们再回到评分过程。为了计算文档得分,需要考虑以下这些因子:
文档权重(documentboost):索引期赋予某个文档的权重值。
字段权重(field boost):查询期赋予某个字段的权重值。
协调因子(coord):基于文档中词项命中个数的协调因子,一个文档命中了查询中的词项越多,得分越高。
逆文档频率(inversedocument frequency):一个基于词项的因子,用来告诉评分公式该词项有多么罕见。逆文档频率越低,词项越罕见。评分公式利用该因子为包含罕见词项的文档加权。
长度范数(length norm):每个字段的基于词项个数的归一化因子(在索引期计算出来并存储在索引中)。一个字段包含的词项数越多,该因子的权重越低,这意味着Apache Lucene评分公式更“喜欢”包含更少词项的字段。
词频(termfrequency):一个基于词项的因子,用来表示一个词项在某个文档中出现了多少次。词频越高,文档得分越高。
查询范数(querynorm):一个基于查询的归一化因子,它等于查询中词项的权重平方和。查询范数使不同查询的得分能相互比较,尽管这种比较通常是困难且不可行的。

得分评判, 我们可以得出一些基本规则:
越多罕见的词项被匹配上,文档得分越高。
文档字段越短(包含更少的词项),文档得分越高。
权重越高(不论是索引期还是查询期赋予的权重值)文档得分越高。

2.2 查询改写
将费时的原始查询类型改写成一个性能更高的查询

例如用户想找出索引中所有name 字段以字母j开头的文档。
这时会查询词库,获取到j开头的全部单词

Term这一列非常重要。就会发现前缀查询已经改写为下面这种查询:
ConstantScore(name :jack name :jane name :joe)

这意味着我们的前缀查询已经改写为常数得分查询( constant score query),该查询由一个布尔查询构成,而这个布尔查询又由三个词项查询构成。Lucene所做的事情就是:枚举索引中的词项,并利用这些词项的信息来构建新的查询。当我们比较改写前后的两个查询的执行效果,会发现改写后的查询性能有所提升,尤其是当索引中有大量不同词项时。
2.3 二次评分
ElasticSearch 中的二次评分指的是重新计算查询返回文档中指定个数文档的得分。这意味着 ElasticSearch 会截取查询返回文档的前N个,并使用预定义的二次评分方法来重新计算它们的得分。
2.4 批量操作
批量取, 批量查询
2.5 排序
Sort
2.7使用过滤器优化查询
ElasticSearch 提供了一种特殊的缓存,即过滤器缓存(filter cache),用来存储过滤器的结果。而且,被缓存的过滤器并不需要消耗过多的内存(因为它们只存储了哪些文档能与过滤器相匹配的相关信息)

我们已经使用了 filtered 查询来同时包含查询和过滤器元素。第一次执行该查询以后过滤器就会被 ElasticSearch 缓存起来,如果后续的其他查询也要使用该过滤器,则它将会被重复利用,从而避免ElasticSearch 重复加载相关数据。

改变ElasticSearch的缓存行为
如果有需要,ElasticSearch 允许用户通过设置 cache和cache key 属性来开启或关闭过滤器的缓存机制

为什么要为cache的key命名也许读者会有疑问,为什么非要手动设置cache key 属性,难道 ElasticSearch 不会自动处理它吗?当然,必要时可以让 ElasticSearch自动处理,但有时候需要更精细地控制缓存行为,就需要手动处理了。例如,已知某些查询很少执行,但又想周期性地清除之前查询的缓存。如果不设置cache key,那么将不得不强制清理全部的过滤器缓存;而如果设置了 cache key,只需执行单个清除命令

第3章 底层索引控制
3.4 准实时、提交、更新及事务日志
在索引期新文档会写入索引段。索引段是独立的Lucene索引,这意味着查询是可以与索引并行的,只是不时会有新增的索引段被添加到可被搜索的索引段集合之中。Apache Lucene 通过创建后续的(基于索引只写一次的特性)segments N文件来实现此功能,且该文件列举了索引中的索引段。这个过程称为提交committing)Lucene以一种安全的方式来执行该操作,能确保索引更改以原子操作方式写入索引,即便有错误发生,也能保证索引数据的一致性。

尽管第一个操作向索引中添加了文档,但它并没有执行提交commit 操作,这就是返回结果没有该数据的原因。然而,一次提交并不足以保证新索引的数据能被搜索到,这是因为 Lucene 使用了一个叫作 Searcher 的抽象类来执行索引的读取。如果索引更新提交了,但Searcher 实例并没有重新打开,那么它觉察不到新索引段的加人。Searcher 重新打开的过程叫作刷新 (refresh)。出于性能考虑,Lucene 推迟了耗时的刷新因此它不会在每次新增一个文档(或批量增加文档)的时候刷新,但 Searcher 会每秒刷新一次。这种刷新已经非常频繁了,然而有很多应用却需要更快的刷新频率。如果碰到这种状要么使用其他技术,要么审视需求是否合理。

ElasticSearch 提供了强制刷新的 API。
例况,如,在例子中可以使用下面的命令:
curl -XGET localhost:9200/test/ refresh
如果在搜索前执行该命令,就会得到我们预期的结果

更改默认的刷新时间
Searcher 自动刷新的时间间隔可以通过以下手段改变:更改
ElasticSearch 配置文件中的index.refreshinterval参数值或者使用配置更新相关的API。
例如:

上面的命令将 Searcher 的自动刷新时间间隔更改为5分钟。请注意,上次刷新后的新增数据并不会被搜索到。

刷新操作是很耗资源的,因此刷新间隔时间越长,索引速度越快。如果需要长时间高速建索引,并且在建索引结束之前暂不执行查询,那么可以考虑将index.refireshinterval参数值设置为-1,然后在建索引结束以后再将该参数恢复为初始值。

事务日志
ElasticSearch 通过使用事务日志(transactionlog)来解决这些问题,它能保存所有的未提交的事务,而 ElasticSearch 会不时创建一个新的日志文件用于记录每个事务的后续操作。当有错误发生时,就会检查事务日志,必要时会再次执行某些操作

准实时读取
事务日志给我们带来一个免费的特性:实时读取(real-timeGET)该功能让返回文档各种版本(包括未提交版本)成为可能。实时读取操作从索引中读取数据时,会先检查事务日志中是否有可用的新版本。如果近期索引没有与事务日志同步,那么索引中的数据将会被忽略,事务日志中最新版本的文档将会被返回。

3.6 控制索引合并
在ElasticSearch 中每个索引都会创建一到多个分片以及零到多个副本,也知道这些分片或副本本质上都是 Lucene 索引,而 Lucene索引又基于多个索引段构建(至少一个索引段)。索引文件中绝大部分数据都是只写一次,读多次,而只有用于保存文档删除信息的文件才会被多次更改。在某些时刻,当某种条件满足时,多个索引段会被拷贝合并到一个更大的索引段,而那些旧的索引段会被抛弃并从磁盘中删除,这个操作称为段合并(segmentmerging)。

也许你会有疑问,为什么非要进行段合并?这是因为:首先,索引段的个数越多,搜索性能越低且耗费内存更多。另外,索引段是不可变的,因而物理上你并不能从中删除信息。也许你碰巧从索引中删除了大量文档,但这些文档只是做了删除标记,物理上并没有被删除。而当段合并发生时,这些标记为删除的文档并没有复制到新的索引段中。如此一来,这减少了最终索引段中的文档数。

选择正确的合并策略
尽管段合并是 Lucene 的责任,ElasticSearch 也允许用户配置想用的段合并策略。到目前为止,有三种可用的合并策略:
tiered(默认)
log_byte_size
log doc

除了可以影响索引合并策略的行为之外,ElasticSearch 还允许我们定制合并策略的执行方式。索引合并调度器(scheduler)分为两种,默认的是并发合并调度器 ConcurrentMerge-Scheduler.

并发合并调度器
该调度器使用多线程执行索引合并操作,其具体过程是:每次开启一个新线程直到线程数达到上限,当达到线程数上限时,必须开启新线程(因为需要进行新的段合并),那么所有索引操作将被挂起,直到至少一个索引合并操作完成。

顺序合并调度器
该调度器非常简单,它使用同一个线程执行所有的索引合并操作。在执行合并时,该线程的其他文档处理都会被挂起,从而索引操作会延迟进行。
第4章 分布式索引架构
选择合适的分片和副本数: 默认配置(5个分片和1个副本)
使用路由进行数据分片存储
调整默认的分片分配器
分片分配器 ShardAllocator 是承担分片分配职责最主要的类。如你记忆中的那样ElasticSearch 集群上的数据分布发生变动时,分片也有相应的变动。例如集群的拓扑结构发生改变(当加入或移除节点)或通过强制重新平衡时。在内部,分配器是 org.elasticsearch.clusterrouting.allocation.allocator.shardsAllocator 接口的一个实现。ElasticSearch 提供了下面两种类型的分配器:
even shard
balanced(默认)

自定义分片分配器
内置的分片分配器可能不适合你的应用场景, 可以自定义分配器, 类似分库分表
这时clusterrouting.allocation.type必须设置成一个类的全限定名,且这个类要实现org.elasticsearch.cluster.routing.allocation.allocatorShardsAllocator 接口
第7章 改善用户搜索体验
如何使用ElasticSearch SuggestAPI改正用户的拼写错误
如何使用term suggester给出单词建议。
如何使用phrasesuggester提示完整词组。
如何配置建议功能以匹配你的需求。
如何使用complete suggester的自动补全功能
如何使用ElasticSearch的各种功能改进搜索相关性。

搜索提示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值