• ElasticSearch常见避坑指南


    一、查询要带上from-size

    在es中query查询如果不指定from-size值,es默认from=0,size=10,默认一次查询10条数据

    如下查询语句,11个唯一id查询,如果不指定from,size,只返回10条数据,而不是11条

    1. {
    2. "query": {
    3. "bool": {
    4. "must": [
    5. {
    6. "terms": {
    7. "id": [4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200]
    8. }
    9. }
    10. ]
    11. }
    12. },
    13. "sort": [
    14. {
    15. "created_time": {
    16. "order": "desc"
    17. }
    18. }
    19. ]
    20. }

     所以正确的查询是加上from=0,size=11,即指定预期的size

    二、查询要指定sort排序字段

    在es中query查询如果不指定sort排序字段,翻页查询,可能会出现重复查询,分页混乱问题。

    如下,每页查询10条,查询多页,可能会有重复的数据返回,此时查询要sort排序字段,尽可能的唯一,如创建时间或者主键、唯一ID字段等。

    1. {
    2. "from": 0,
    3. "size": 10,
    4. "query": {
    5. "bool": {
    6. "must": [{
    7. "term": {
    8. "month": "2022-12"
    9. }
    10. }]
    11. }
    12. }
    13. }

    总体来说,这是由于 ES 的分片存储与分片检索机制导致的。一个常见的原因就是ES的_score评分引起的。ES默认的排序,恰恰就是按 _score倒序。 在全部doc的_score 都是0分的时候,分页就会错乱,有时候出现在第一页的结果很可能会重复出现在第二页,第三页 (取决于当时shards 返回的结果的顺序)

    三、from-size分页设置窗口大小

    如果初次使用且对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

    1. PUT my_index/_settings
    2. {"index.max_result_window":"800000"}

    之所以es默认设置最大查询量1w,与es的分布式存储和from+size的分页原理有关,可以参考之前的文章

    四、should谨慎与must、filter等平级使用

    在bool查询时候,should是选择性匹配,是or的关系。但是使用must、must_not、filter查询时候,bool下还带有与之平级的should条件,这时候should条件就失效了,满足不满足都可以。

    如下查询,正常思维理解,在must下都符合条件的前提下,当should下的字段至少有一个以上符合条件时候,才会查询到数据,然而,实际并非如此,当should下字段都不符合条件时候也会查询到数据

    1. {
    2. "from": 0,
    3. "size": 20,
    4. "query": {
    5. "bool": {
    6. "must": [
    7. {
    8. "term": {"order_id": { "value": 2133456244}}
    9. }
    10. ],
    11. "should": [
    12. {
    13. "term": {"creator": {"value": "zhangsanhh"}}
    14. },
    15. {
    16. "terms": {"dept_id_1": [8636,4460]
    17. }
    18. }
    19. ]
    20. }
    21. }
    22. }

    已知的有两种简单的方法可以避免此问题

    (1)指定minimum_should_match

    一种是在查询中增加minimum_should_match参数,指定值1,表示should下条件要至少满足一个条件的时候才返回数据

    1. {
    2. "from": 0,
    3. "size": 20,
    4. "query": {
    5. "bool": {
    6. "must": [
    7. {
    8. "term": {"order_id": { "value": 2133456244}}
    9. }
    10. ],
    11. "should": [
    12. {
    13. "term": {"creator": {"value": "zhangsanhh"}}
    14. },
    15. {
    16. "terms": {"dept_id_1": [8636,4460]
    17. }
    18. }
    19. ],
    20. "minimum_should_match": 1,
    21. }
    22. }
    23. }

    (2)should降级

    另一种把should单独包装为一个bool,降级到must下,把其整体作为must下的一个条件查询

    1. {
    2. "from": 0,
    3. "size": 20,
    4. "query": {
    5. "bool": {
    6. "must": [{
    7. "term": {"order_id": {"value": 2133456244}}
    8. },
    9. {
    10. "term": {"sku_id": {"value": 1000342267312}}
    11. }, {
    12. "bool": {
    13. "should": [{
    14. "term": {"creator": {"value": "zhangsanhh"}}
    15. },
    16. {
    17. "terms": {"dept_id_1": [8636, 4460]}
    18. }
    19. ]
    20. }
    21. }
    22. ]
    23. }
    24. }
    25. }
  • 相关阅读:
    A40I工控主板(SBC-X40I)网络接口测试
    [附源码]计算机毕业设计基于Springboot楼盘销售管理系统
    “蔚来杯“2022牛客暑期多校训练营(加赛) G.Good red-string
    centos升级openssh
    图的基本表示方法
    Linux零基础入门(一)初识Linux
    Simulink的serial系列无法识别硬件串口的解决方法
    【AIGC调研系列】MiniCPM-Llama3-V2.5模型与GPT-4V对比
    [gstreamer] overview of gstreamer
    HTML+CSS期末网页设计前端作品(大三)
  • 原文地址:https://blog.csdn.net/lzxlfly/article/details/128029656