在es中query查询如果不指定from-size值,es默认from=0,size=10,默认一次查询10条数据
如下查询语句,11个唯一id查询,如果不指定from,size,只返回10条数据,而不是11条
- {
- "query": {
- "bool": {
- "must": [
- {
- "terms": {
- "id": [4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200]
- }
- }
- ]
- }
- },
- "sort": [
- {
- "created_time": {
- "order": "desc"
- }
- }
- ]
- }
所以正确的查询是加上from=0,size=11,即指定预期的size
在es中query查询如果不指定sort排序字段,翻页查询,可能会出现重复查询,分页混乱问题。
如下,每页查询10条,查询多页,可能会有重复的数据返回,此时查询要sort排序字段,尽可能的唯一,如创建时间或者主键、唯一ID字段等。
- {
- "from": 0,
- "size": 10,
- "query": {
- "bool": {
- "must": [{
- "term": {
- "month": "2022-12"
- }
- }]
- }
- }
- }
总体来说,这是由于 ES 的分片存储与分片检索机制导致的。一个常见的原因就是ES的_score评分引起的。ES默认的排序,恰恰就是按 _score倒序。 在全部doc的_score 都是0分的时候,分页就会错乱,有时候出现在第一页的结果很可能会重复出现在第二页,第三页 (取决于当时shards 返回的结果的顺序)
如果初次使用且对es不熟悉的话,当from + size分页查询超过10000时候,会报如下异常:
Result window is too large, from + size must be less than or equal to: [10000] but was [22020]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting
上边 from+size=(pageNum-1)*size+size=(1101-1)*20+20=22020>10000,抛出了异常
当然10000也可以调整,如最大上限调整为800000
- PUT my_index/_settings
-
- {"index.max_result_window":"800000"}
之所以es默认设置最大查询量1w,与es的分布式存储和from+size的分页原理有关,可以参考之前的文章
在bool查询时候,should是选择性匹配,是or的关系。但是使用must、must_not、filter查询时候,bool下还带有与之平级的should条件,这时候should条件就失效了,满足不满足都可以。
如下查询,正常思维理解,在must下都符合条件的前提下,当should下的字段至少有一个以上符合条件时候,才会查询到数据,然而,实际并非如此,当should下字段都不符合条件时候也会查询到数据
- {
- "from": 0,
- "size": 20,
- "query": {
- "bool": {
- "must": [
- {
- "term": {"order_id": { "value": 2133456244}}
- }
- ],
- "should": [
- {
- "term": {"creator": {"value": "zhangsanhh"}}
- },
- {
- "terms": {"dept_id_1": [8636,4460]
- }
- }
- ]
- }
- }
- }
已知的有两种简单的方法可以避免此问题
(1)指定minimum_should_match
一种是在查询中增加minimum_should_match参数,指定值1,表示should下条件要至少满足一个条件的时候才返回数据
- {
- "from": 0,
- "size": 20,
- "query": {
- "bool": {
- "must": [
- {
- "term": {"order_id": { "value": 2133456244}}
- }
- ],
- "should": [
- {
- "term": {"creator": {"value": "zhangsanhh"}}
- },
- {
- "terms": {"dept_id_1": [8636,4460]
- }
- }
- ],
- "minimum_should_match": 1,
- }
- }
- }
(2)should降级
另一种把should单独包装为一个bool,降级到must下,把其整体作为must下的一个条件查询
- {
- "from": 0,
- "size": 20,
- "query": {
- "bool": {
- "must": [{
- "term": {"order_id": {"value": 2133456244}}
- },
- {
- "term": {"sku_id": {"value": 1000342267312}}
- }, {
- "bool": {
- "should": [{
- "term": {"creator": {"value": "zhangsanhh"}}
- },
- {
- "terms": {"dept_id_1": [8636, 4460]}
- }
- ]
- }
- }
- ]
- }
- }
- }