解决ES只能查询10000条数据的问题

这篇具有很好参考价值的文章主要介绍了解决ES只能查询10000条数据的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇文章是翻译过来的,原文在此,需要科学上网。

当查询页很深或者查询的数据量很大时,深查询就会出现。es 的自我保护机制允许的一次最大查询量是 10000 条数据。在请求中加入trackTotalHits(true) 可以解除10000条的上限。

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().trackTotalHits(true);

三种批量查询

from size

这种实现方式有点类似于 MySQL 中的 limit。性能差,实现简单,适用于少量数据,但优点是可以随机跳转页面。

package com.example.es.test;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class ESTest_from_size {

       public static final Logger logger = LoggerFactory.getLogger(ESTest_searchAfter.class);

        public static void main(String[] args) throws Exception{
            long startTime = System.currentTimeMillis();
            RestHighLevelClient esClient = new RestHighLevelClient(
                    RestClient.builder(new HttpHost("localhost", 9200, "http")));
            SearchRequest searchRequest = new SearchRequest("audit2");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            // 偏移量(第几页)
            sourceBuilder.from(0);
            // 每页多少个元素。
            sourceBuilder.size(1000);
            // 按照指定属性排序。
            sourceBuilder.sort(SortBuilders.fieldSort("operationtime").order(SortOrder.DESC));
            searchRequest.source(sourceBuilder);
            SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHit[] hits = searchResponse.getHits().getHits();
            List<Map<String, Object>> result = new ArrayList<>();
            if (hits != null && hits.length > 0) {
                for (SearchHit hit : hits) {
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                    result.add(sourceAsMap);
                }
            }
            logger.info("The number of data queried is:{}", result.size());
            esClient.close();
            logger.info("Running time: " + (System.currentTimeMillis() - startTime) + "ms");
        }
    }
}

scroll

高效的滚动查询,第一个查询会在内存中保存一个历史快照和光标(scroll_id)来记录当前消息查询的终止位置。下次查询会从光标记录的位置往后进行查询。这种方式性能好,不是事实的,一般用于海量数据导出或者重建索引。但是 scroll_id 有过期时间,两次查询之间如果 scroll_id 过期了,第二次查询会抛异常“找不到 “scroll_id”。假如场景是读一批数据,处理,再读再处理,恰好处理过称很花费时间且不确定,那很可能会遇到 scroll_id 过期。

package com.example.es.test;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.*;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author 
 * @Description  java Realize scroll scrolling query
 * @date 2021/12/08 14:09
 */
public class ESTest_Scroll {

    public static final Logger logger = LoggerFactory.getLogger(ESTest_Scroll.class);

    public static void main(String[] args) throws Exception{
        long startTime = System.currentTimeMillis();
        // Create ES client
        RestHighLevelClient esClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );
        // 1. Create searchRequest
        SearchRequest searchRequest = new SearchRequest("audit2");
        // 2. Specify scroll information
        searchRequest.scroll(TimeValue.timeValueMinutes(1L));
        // 3. Specify query criteria
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(1000);
        searchSourceBuilder.sort(SortBuilders.fieldSort("operationtime").order(SortOrder.DESC));//Multi condition query
        searchRequest.source(searchSourceBuilder);
        //4. Get the returned result scrollId, source
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT); //Initialize the search context by sending an initial search request
        String scrollId = searchResponse.getScrollId();
        SearchHit[] searchHits = searchResponse.getHits().getHits();
        List<Map<String, Object>> result = new ArrayList<>();
        for (SearchHit hit: searchHits) {
            result.add(hit.getSourceAsMap());
        }
        // java is the same. We need to query twice. First, find out our home page
        // After the query, we need to get his id
        // Then use his id to query his next page
        while (true) {
            //5. Loop - create SearchScrollRequest create a new search scroll request and save the last returned scroll identifier and scroll interval
            // Get scrollId to query the next page
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            //6. Specifies the lifetime of the scrollId
            scrollRequest.scroll(TimeValue.timeValueMinutes(1L));
            //7. Execute the query to get the returned results
            SearchResponse scrollResp = esClient.scroll(scrollRequest, RequestOptions.DEFAULT);
            //8. Judge whether the data is queried and output
            SearchHit[] hits = scrollResp.getHits().getHits();
            //Cycle output next page
            if (hits != null && hits.length > 0) {
                for (SearchHit hit : hits) {
                    result.add(hit.getSourceAsMap());
                }
            } else {
                //9. Judge that no data is found and exit the cycle
                break;
            }
        }
        //After checking, we delete the id stored in the cache. After scrolling, clear the scrolling context
        //10. Create ClearScrollRequest
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        //11. Specify scrollId
        clearScrollRequest.addScrollId(scrollId);
        //12. Delete scrollId
        ClearScrollResponse clearScrollResponse = esClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
        //13. Output results
        boolean succeeded = clearScrollResponse.isSucceeded();
        logger.info("delete scrollId: {}", succeeded);
        logger.info("Total number of queries:{}", result.size());
        // Close client
        esClient.close();
        logger.info("Running time: " + (System.currentTimeMillis() - startTime) + "ms");
    }

}

search after

顾名思义,从指定的某个数据后面开始读。这种方式不能随机跳转分页,只能一页一页地读取数据,而且必须用一个唯一且不重复的属性对待查数据进行排序。这种方式的优点是批量查询但不依赖于 scroll_id,所以后续处理可以不考虑耗费时间的问题。文章来源地址https://www.toymoban.com/news/detail-527963.html

package com.example.es.test;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author
 * @Description  es Search for_ After method
 * @date 2022/01/11 14:04
 */
public class ESTest_searchAfter {

    public static final Logger logger = LoggerFactory.getLogger(ESTest_searchAfter.class);

    public static void main(String[] args) throws Exception{
        long startTime = System.currentTimeMillis();
        // Create ES client
        RestHighLevelClient esClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );
        // 1. Create searchRequest
        SearchRequest searchRequest = new SearchRequest("audit2");
        // 2. Specify query criteria
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().trackTotalHits(true);//Track must be added_ total_ Hits, or only 10000 will be displayed
        //Set the number of data queried per page
        sourceBuilder.size(1000);
        // Set unique sort value positioning
        sourceBuilder.sort(SortBuilders.fieldSort("operationtime").order(SortOrder.DESC));//Multi condition query
        //Add the sourceBuilder object to the search request
        searchRequest.source(sourceBuilder);
        // Send request
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits1 = searchResponse.getHits().getHits();
        List<Map<String, Object>> result = new ArrayList<>();
        if (hits1 != null && hits1.length > 0) {
            do {
                for (SearchHit hit : hits1) {
                    // Get required data
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                    result.add(sourceAsMap);
                }
                // Get the last sort value sort, which is used to record the data retrieval from this place next time
                SearchHit[] hits = searchResponse.getHits().getHits();
                Object[] lastNum = hits[hits.length - 1].getSortValues();
                // Set the last sort value of searchAfter
                sourceBuilder.searchAfter(lastNum);
                searchRequest.source(sourceBuilder);
                // Make the next query
                searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
            } while (searchResponse.getHits().getHits().length != 0);
        }
        logger.info("The number of data queried is:{}", result.size());
        // Close client
        esClient.close();
        logger.info("Running time: " + (System.currentTimeMillis() - startTime) + "ms");
    }

}

到了这里,关于解决ES只能查询10000条数据的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决 Elasticsearch 分页查询记录超过10000时异常

    查询结果中 hits.total.value 值最大为10000的限制 解决方法: 1、 请求设置rest_total_hits_as_int=true 注意参数需要放在请求头上 2、修改setting的值  

    2024年02月07日
    浏览(41)
  • Elasticsearch 查询超过10000 的解决方案 - Python

    法1:修改 设置 max_result_size (不推荐) 法2: scroll 分页 法3: search_after 分页 还有一个方法是在参考文章2里面提到的 track_total_hits ,但是我测试的时候没起作用,目前还不太清楚原因。。。 我看参考文章里说到search_after 分页要比scroll快,但是在我的数据上是scroll要快很多,

    2024年01月23日
    浏览(50)
  • ElasticSearch - 查询大于10000条的数据

    当我们使用 ES 的时候,有时会比较关心匹配到的文档总数是多少,所以在查询得到结果后会使用 hits.total.value 这个值作为匹配的总数。但是,es官方默认限制索引查询最多只能查询10000条数据。 因此可以将\\\"track_total_hits\\\"置为true ,解除最多查询10000条的限制:

    2024年02月16日
    浏览(49)
  • elasticSearch大量数据查询导出报错解决es

    elasticsearch的client包下的HeapBufferedAsyncResponseConsumer类中传入了bufferLimit,该值 org.apache.http.nio.protocol.HttpAsyncResponseConsumer 的默认实现。在堆内存中缓冲整个响应内容,这意味着缓冲区的大小等于响应的内容长度。根据可配置的参数限制可以读取的响应的大小。如果实体长于配置

    2023年04月16日
    浏览(46)
  • ElasticSearch 10000条查询数量限制

    我们将库存快照数据导入ES后发现要分页查询10000条以后的记录会报错,这是因为ES通过index.max_result_window这个参数控制能够获取数据总数from+size最大值,默认限制是10000条,因为ES考虑到数据要从其它节点上报到协调节点如果搜索请求的数据越多,会导致ES协调节点占用的堆内

    2024年02月06日
    浏览(40)
  • 【问题解决】ElasticSearch分页查询时数据顺序错乱/不一致的问题

    问题描述: 使用ElasticSearch分页查询时,每次输入同样的分页参数以及查询条件,得到的结果不一致的问题。 问题分析: ElasticSearch中索引可能是由多个分片构成的,并且每个分片可能拥有多个副本,其对应的设置时索引建立时的设置。 number_of_shards:索引拥有多少个分片 n

    2024年02月02日
    浏览(58)
  • 解决ElasticSearch本地只能通过localhost访问不能通过IP访问的问题。

    安装完成后只能通过localhost访问,不能通过ip进行访问,解决以下三点 1、检查防火墙是否已经关闭         sudo systemctl status firewalld  查看防火墙状态 如果是active就修改         sudo systemctl stop firewalld   关闭防火墙         sudo systemctl disable firewalld   这个方式可以永久

    2024年02月04日
    浏览(45)
  • Graylog日志查询超过10000限制问题

    在使用graylog时,默认分页查询存在限制,真实使用不能满足,需要我们手动处理。当查询超过执行长度时,会出现一下错误提示 问题描述 查询超过 10000 页, Elasticsearch 出现异常 解决方案 方案一:修改配置文件,重启 Elasticsearch 服务【 Elasticsearch5.x 版本以后不支持】 修改

    2024年02月04日
    浏览(57)
  • java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制。

    (1)首先我们要明白es的查询机制:ES的搜索是分2个阶段进行的,即 Query阶段和Fetch阶段 。 Query阶段 比较轻量级,通过查询倒排索引,获取满足查询结果的文档ID列表。 Fetch阶段 比较重,需要将每个分片的查询结果取回,在协调结点进行 全局 排序。 通过From+size这种方式分批

    2024年02月03日
    浏览(85)
  • Elasticsearch ES操作:查询数据(全部、分页、单条)

    查询 条件查询 指定条数 返回结果

    2024年02月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包