首页 > 其他分享 >elasticsearch的查询数大于10000查询失败

elasticsearch的查询数大于10000查询失败

时间:2022-10-15 19:24:17浏览次数:76  
标签:search 10000 ElasticsearchException results 查询 window elasticsearch new

错误信息

Caused by: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Result window is too large, from + size must be less than or equal to: [10000] but was [11000]. 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.]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Result window is too large, from + size must be less than or equal to: [10000] but was [11000]. 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.]];
	at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:491)
	at org.elasticsearch.ElasticsearchException.fromXContent(ElasticsearchException.java:402)
	at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:432)
	at org.elasticsearch.ElasticsearchException.failureFromXContent(ElasticsearchException.java:598)
	at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:170)
	... 122 more

错误原因

elasticsearch官方提及:不能使用from和size翻阅超过 10,000 个点击。此限制是由index.max_result_window索引设置设置的保护措施。

处理方法:

方法1.增加max_result_window的大小

PUT tweets_v1/_settings
{
    "index": {
        "max_result_window": 1000000
    }
}

注:手动增加max_result_window大小,会导致内存与CPU占用过高,并且不好保证手动设置的大小,在一定时间后会不会任然够用,故而不推荐使用。

方法2.使用Scroll API(滚动查询)

    @Resource
    private ElasticsearchRestTemplate template;

    // 第一次获取数据
    public ScrollPageResult<TweetsEntity> scrollStart(Integer pageSize) {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withSort(new FieldSortBuilder("createTime"))
                .build();
        // 设置每页数据量
        nativeSearchQuery.setMaxResults(pageSize);
        // 设置滚动id的存在时间
        long scrollTimeInMillis = 600 * 1000;
        // 第一次查询
        SearchScrollHits<TweetsEntity> searchScrollHits = template.searchScrollStart(scrollTimeInMillis, nativeSearchQuery, TweetsEntity.class, IndexCoordinates.of("tweets_v1"));

        // 获取下一次的滚动id,时间有限
        String scrollId = searchScrollHits.getScrollId();

        // 获取数据
        List<TweetsEntity> results = new ArrayList<>();
        searchScrollHits.getSearchHits().iterator().forEachRemaining(item -> results.add(item.getContent()));

        // 数据返回
        return ScrollPageResult.of(scrollId, results);
    }

    // 获取下一页数据
    public ScrollPageResult<TweetsEntity> scrollNext(String scrollId) {
        long scrollTimeInMillis = 60 * 1000;
        SearchScrollHits<TweetsEntity> searchScrollHits = template.searchScrollContinue(scrollId, scrollTimeInMillis, TweetsEntity.class, IndexCoordinates.of("tweets_v1"));

        // 获取下一次的滚动id,时间有限
        String scrollId2 = searchScrollHits.getScrollId();

        // 获取数据
        List<TweetsEntity> results = new ArrayList<>();
        searchScrollHits.getSearchHits().iterator().forEachRemaining(item -> results.add(item.getContent()));

        if (searchScrollHits.hasSearchHits()) {
            // 数据返回
            return ScrollPageResult.of(scrollId2, results);
        } else {
            // 清除 scroll
            template.searchScrollClear(Collections.singletonList(scrollId2));
            // 数据返回
            return ScrollPageResult.of(null, results);
        }
    }

注:elasticsearch官方也是不推荐使用Scroll API的。
一是滚动搜索的结果反映了初始搜索请求时的索引状态,随后的索引或文档更改只会影响以后的搜索和滚动请求;
二是Scroll API需要Scroll ID。要获取Scroll ID,则需要设置请求保留搜索上下文多长时间,只有在时间中生成的Scroll ID才有效。

方法3.使用search_after参数

    @Resource
    private ElasticsearchRestTemplate template;
    // 第一次获取
    public SearchAfterPageResult<TweetsEntity> searchAfterStart(Integer pageSize) {
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())
                .withPageable(Pageable.ofSize(pageSize))
                .withSort(Sort.by("createTime")).build();
        SearchHits<TweetsEntity> search = template.search(searchQuery, TweetsEntity.class, IndexCoordinates.of("tweets_v1"));
        List<SearchHit<TweetsEntity>> list = search.getSearchHits();

        // 获取数据
        List<TweetsEntity> results = new ArrayList<>();
        search.getSearchHits().iterator().forEachRemaining(item -> results.add(item.getContent()));

        // 数据返回
        return SearchAfterPageResult.of(list.get(list.size() - 1).getSortValues(), results);
    }

    // 获取下一页数据
    public SearchAfterPageResult<TweetsEntity> searchAfterNext(List<Object> searchAfter, Integer pageSize) {
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())
                .withPageable(Pageable.ofSize(pageSize))
                .withSearchAfter(searchAfter)
                .withSort(Sort.by("createTime")).build();
        SearchHits<TweetsEntity> search = null;
        try {
            search = template.search(searchQuery, TweetsEntity.class, IndexCoordinates.of("tweets_v1"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        List<SearchHit<TweetsEntity>> list = search.getSearchHits();

        // 获取数据
        List<TweetsEntity> results = new ArrayList<>();
        search.getSearchHits().iterator().forEachRemaining(item -> results.add(item.getContent()));

        // 数据返回
        if (pageSize.equals(results.size())) {
            return SearchAfterPageResult.of(list.get(list.size() - 1).getSortValues(), results);
        } else {
            return SearchAfterPageResult.of(null, results);
        }
    }

注: Elasticsearch 使用 Lucene 的内部文档 ID 作为决胜局。这些内部文档 ID 在相同数据的副本中可能完全不同。当分页搜索命中时,您可能偶尔会看到具有相同排序值的文档的排序不一致。
更多详细资料:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/paginate-search-results.html#search-after

我使用的elasticsearch高版本,在高版本中官方已经不推荐使用RestHighLevelClient,而是使用ElasticsearchRestTemplate。

标签:search,10000,ElasticsearchException,results,查询,window,elasticsearch,new
From: https://www.cnblogs.com/purple910/p/16794827.html

相关文章

  • ElasticSearch
    选型因为数据库的like等操作会导致索引失效,进而导致查询性能低,功能弱,从而引入ElasticSearch通过倒排索引解决全文检索性能和功能的问题。数据结构倒排索引一般包含两......
  • thinkphp5 如何查询 以逗号间隔的数据
    例如1,2,3,4之类的id或者其他组成的数值字符串存入字段中,然后会有查询的需求,例如我们需要查询包含1的所有的数据,这时我们可以使用find_in_set()函数;$id=4;Db::name('men......
  • sql left联表查询将结果插入到别一数据库表中
    a数据库多表查询selecta.id,a.title,a.typeid,b.body,a.pubdate,a.keywords,a.descriptionfromras_archivesaleftjoinras_addonarticlebona.id=b.aidwherea.t......
  • Access自定义函数,实现递归查询
    Access自定义函数,实现递归查询介绍有一个数据表,表名为测试表,表结构及内容如下:表结构字段名称数据类型说明(可选)编号数字主键父节点数字关联编号字段......
  • DOS窗口命令和单表简单查询
    相关术语:DB:数据库:在硬盘上以文件的方式存在DBMS:数据库管理系统:例如mysql,oracle,sqlserver…SQL:一门适用于所有DBMS,对DB进行操作的标准规划语言,DQL:数据库查询语句select,D......
  • 如何批量查找第N个相同查询值所对应的数据?
    Excel情报局职场联盟Excel生产挖掘分享Excel基础技能Excel爱好者大本营用1%的Excel基础搞定99%的职场问题做一个超级实用的Excel公众号Excel是门手艺玩转需要勇气数万Excel......
  • 08. MyBatis的查询专题
    一、环境的搭建1.1、数据的准备CREATEDATABASEIFNOTEXISTSdb_test;USEdb_test;CREATETABLEIFNOTEXISTSt_emp( emp_idINTPRIMARYKEYauto_increment, ......
  • Elasticsearch使用terms聚合之后进行分页排序
    引言elasticsearch中实现聚合也非常常见,同时es的数据量一般比较大,因此聚合结果比较多,像terms聚合默认只返回10条聚合结果,所以聚合之后进行分页,也是非常常见的操作。es的t......
  • WDA DEMO 03: 根据选择条件查询并显示
    下面开始干货:事先声明下,本人没参加过培训,也没看过完整的标准教程,所以一直都是野路子,土八路。所以文章中不足以及不正确的地方请大家帮忙指正。SE80新建。然后新建一个Attri......
  • 【Oracle】多表联合查询超时问题排查
    文中使用的Oracle版本为10g。本文内容将涉及大规模SQL联合查询优化内容,本人尽可能讲得容易理解一些,若有看不懂的地方是本人表述不清楚,望各位海涵。此外文章是2016年写的,那时......