优化日期搜索
在使用日期范围检索时,使用now的查询通常不能缓存,因为匹配到的范围一直在变化。但是,从用户体验的角度来看,切换到一个完整的日期通常是可以接受的,这样可以更好地利用查询缓存。
curl -X GET "localhost:9200/index/_search?pretty" -H 'Content-Type: application/json' -d'{"query": {"constant_score": {"filter": {"range": {"my_date": {"gte": "now-1h/m","lte": "now/m" } } } } }}'
代替
curl -X PUT "localhost:9200/index/_doc/1?pretty" -H 'Content-Type: application/json' -d'{"my_date": "2016-05-11T16:30:55.328Z"}'curl -X GET "localhost:9200/index/_search?pretty" -H 'Content-Type: application/json' -d'{"query": {"constant_score": {"filter": {"range": {"my_date": {"gte": "now-1h","lte": "now" } } } } }}'
为只读索引执行force-merge
为不再更新的只读索引执行force merge,将Lucene索引合并为单个分段,可以提升查询速度。当一个Lucene索引存在多个分段时,每个分段会单独执行搜索再将结果合并,将只读索引强制合并为一个Lucene分段不仅可以优化搜索过程,对索引恢复速度也有好处。基于日期进行轮询的索引的旧数据一般都不会再更新。此前的章节中说过,应该避免持续地写一个固定的索引,直到它巨大无比,而应该按一定的策略,例如,每天生成一个新的索引,然后用别名关联,或者使用索引通配符。这样,可以每天选一个时间点对昨天的索引执行force-merge、Shrink等操作。
只读的索引可能会从合并到单个段中受益。对于基于时间的索引,通常是这种情况:只有当前时间范围的索引才能获取新文档,而较旧的索引则为只读。强制合并到单个段中的分片可以使用更简单,更有效的数据结构来执行搜索。
不要强行合并仍在写入的索引,或者将来会再次写入的索引。而是,根据需要依靠自动后台合并过程执行合并,以保持索引平稳运行。如果继续写入强制合并的索引,则其性能可能会变得更差。
预热全局序号
全局序号是一种数据结构,用于在keyword字段上运行terms聚合。它用一个数值来代表字段中的字符串值,然后为每一数值分配一个 bucket。这需要一个对 global ordinals 和 bucket的构建过程。默认情况下,它们被延迟构建,因为ES不知道哪些字段将用于 terms聚合,哪些字段不会。可以通过配置映射在刷新(refresh)时告诉ES预先加载全局序数:
curl -X PUT "localhost:9200/index?pretty" -H 'Content-Type: application/json' -d'{"mappings": {"_doc": {"properties": {"foo": {"type": "keyword","eager_global_ordinals": true } } } }}'
execution hint
terms聚合有两种不同的机制:
1 通过直接使用字段值来聚合每个桶的数据(map)。
2 通过使用字段的全局序号并为每个全局序号分配一个bucket(global_ordinals)。
ES 使用 global_ordinals 作为 keyword 字段的默认选项,它使用全局序号动态地分配bucket,因此内存使用与聚合结果中的字段数量是线性关系。在大部分情况下,这种方式的速度很快。当查询只会匹配少量文档时,可以考虑使用 map。默认情况下,map 只在脚本上运行聚合时使用,因为它们没有序数。
转换查询表达式
在组合查询中可以通过bool过滤器进行and、or和not的多个逻辑组合检索,这种组合查询中的表达式在下面的情况下可以做等价转换:(A|B) & (C|D) ==> (A&C) | (A&D) | (B&C) | (B&D )
调节搜索请求中的bached_reduce_size
该字段是搜索请求中的一个参数。默认情况下,聚合操作在协调节点需要等所有的分片都取回结果后才执行,使用 batched_reduce_size 参数可以不等待全部分片返回结果,而是在指定数量的分片返回结果之后就可以先处理一部分(reduce)。这样可以避免协调节点在等待全部结果的过程中占用大量内存,避免极端情况下可能导致的OOM。该字段的默认值为512,从ES 5.4开始支持。