ES JPA 带排序查询报错,java.lang.IllegalArgumentException: numHits must be > 0

简介

当你的 ES 版本 >= 7.6, 单个索引的文档数 > 512, 查询时使用JPA 查询,或者手动优化 size = 0, 均会出现该问题。

例如:

public interface A extends ElasticsearchRepository<FinanceReportDay, String> {
    
    
    List<FinanceReportDay> findByStockCodeOrderByPublishTimeAsc(String stockCode);
}

则会出现以下报错信息:

java.lang.IllegalArgumentException: numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count.

问题详情

经过调试发现,JPA 会对查询语句进行优化,会先进行 count 查询,然后再进行实际查询,并且优化后的查询语句如下所示:

POST stock_finance_report_day/_search
{
    
    
  "from": 0,
  "size": 0,
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "query_string": {
    
    
            "query": "1111",
            "fields": [
              "stock_code^1.0"
            ],
            "type": "best_fields",
            "default_operator": "and",
            "max_determinized_states": 10000,
            "enable_position_increments": true,
            "fuzziness": "AUTO",
            "fuzzy_prefix_length": 0,
            "fuzzy_max_expansions": 50,
            "phrase_slop": 0,
            "escape": false,
            "auto_generate_synonyms_phrase_query": true,
            "fuzzy_transpositions": true,
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "version": true,
  "sort": [
    {
    
    
      "publish_time": {
    
    
        "order": "asc"
      }
    }
  ],
  "track_total_hits": 2147483647
}

问题原因

Google 后,发现该问题,是ES 的 BUG,相关 issue: Search can fail when size is 0 and long sort optimization enabled.

问题的原因就在于 ES 7.6 版本后对于文档数 > 512 的排序查询进行了优化,导致了如果查询时同时使用了size = 0, track_total_hits就会出现该问题。

解决方案

方案一

升级版本升级 ES版本至 8.0(不确定是否已经修复,详情参数对应 issue

方案二

使用非 JPA 使用 RestHighClient 进行手动查询

方案三

手动查询出所有数据(如果数据量不大于单次最大请求数量,默认10000条),然后手动进行排序

猜你喜欢

转载自blog.csdn.net/assember/article/details/123926169
今日推荐