ES查询踩两个坑

ElasticSearch偶尔查询不到数据

1.数据刷新策略

现象:每次insert之后,立刻查询es的数据是有可能查不到的,因为es从内存写到磁盘需要时间

原因:es默认每1s执行一次refresh,因此文档实时性被提高到1s,这也是es被称为近实时的原因

解决方法:写的时候指定数据刷新策略, request().setRefreshPolicy(RefreshPolicy.IMMEDIATE);

  枚举org.elasticsearch.action.support.WriteRequest.RefreshPolicy定义了三种策略:

NONE,

IMMEDIATE,

WAIT_UNTIL; 

2.查询条件中含有中文导致查询不到数据

elasticsearch 里默认的IK分词器是会将每一个中文都进行了分词的切割,

所以你直接想查一整个词,或者一整句话是无返回结果的。

解决办法:

查询条件字增加.keyword后缀

QueryBuilders.termQuery("filed.keyword", "查询中文内容")

解释:ElasticSearch 5.0以后,string类型有重大变更,移除了string类型,string字段被拆分成两种新的数据类型: text用于全文搜索的,而keyword用于关键词搜索

参考文章:https://www.jianshu.com/p/26744eb914a8

每次查询最大只能查10000条

通过资料的查阅,发现默认值是10000,如果要查询大于10000条,我们就需要修改es的max_result_window默认值

解决方法:

我们在创建索引的时候 设置:"index.max_result_window": "10000", 这个值默认一万,我们可以改成自己想要的值

也可以使用ES的Scroll滚动查询

ES性能优化

1. 因为ES不能改变分片数量,所以创建索引的时候要指定好分片数量

ES 默认为一个索引创建 5 个主分片, 并分别为每个分片创建一个副本分片。

解决办法:合理的分片数量可以提高写入性能和稳定性。

  分片数可以理解为MySQL中的分库分表

  ES查询主要分为两类:单ID查询以及分页查询。

  分片数越大,集群横向扩容规模也更大,根据分片路由的单ID查询吞吐量也能大大提升,但聚合的分页查询性能则将降低;

  分片数越小,集群横向扩容规模也更小,单ID的查询性能也会下降,但分页查询的性能将会提升。

  ES的查询原理

2、避免深分页查询ES集群的分页查询支持from和size参数,

  查询的时候,每个分片必须构造一个长度为from+size的优先队列,

  然后回传到网关节点,网关节点再对这些优先队列进行排序找到正确的size个文档。

  假设在一个有6个主分片的索引中,from为10000,size为10,每个分片必须产生10010个结果,

  在网关节点中汇聚合并60060个结果,最终找到符合要求的10个文档。

  由此可见,当from足够大的时候,就算不发生OOM,也会影响到CPU和带宽等,从而影响到整个集群的性能。

  所以应该避免深分页查询,尽量不去使用。

解决办法:可以使用ES的Scroll滚动查询

  scroll 可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,

  相当于一个锚标记 ,随后再次滚动搜索会需要上一次搜索滚动id,根据这个进行下一次的搜索请求。

  每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的。

  性能会比上面说的分页性能要高很多,基本上都是毫秒级的。

  这个适合于那种类似微博下拉翻页的,不能随意跳到任何一页的场景。

具体官网文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html

原文地址:https://www.cnblogs.com/ssskkk/p/15417053.html