全国网站备案查询,中国企业网官方网站下载,网站认证费用,潍坊建筑公司排名基于scroll滚动技术实现大数据量搜索 如果一次性要查出来比如10万条数据#xff0c;那么性能会很差#xff0c;此时一般会采取用scroll滚动查询#xff0c;一批一批的查#xff0c;直到所有数据都查询完为止。 scroll搜索会在第一次搜索的时候#xff0c;保存一个当时的视…
基于scroll滚动技术实现大数据量搜索 如果一次性要查出来比如10万条数据那么性能会很差此时一般会采取用scroll滚动查询一批一批的查直到所有数据都查询完为止。 scroll搜索会在第一次搜索的时候保存一个当时的视图快照之后只会基于该旧的视图快照提供数据搜索如果这个期间数据变更是不会让用户看到的 采用基于_doc不使用_score进行排序的方式性能较高 每次发送scroll请求我们还需要指定一个scroll参数指定一个时间窗口每次搜索请求只要在这个事件窗口内能完成就可以了 # sort默认是相关度排序sort:[{FIELD:{order:desc}}],不按_score排序按_doc排序
# size设置的是这批查三条
# 第一次查询会生成快照
GET /lib3/user/_search?scroll1m #这一批查询在一分钟内完成
{query:{match:{}},sort:[ _doc],size:3
}# 第二次查询通过第一次的快照ID来查询后面以此类推
GET /_search/scroll
{scroll:1m,scroll_id:DnF1ZXJ5VGhIbkXIdGNoAwAAAAAAAAAdFkEwRENOVTdnUUJPWVZUd1p2WE5hV2cAAAAAAAAAHhZBMERDTIU3Z1FCT1|WVHdadIhOYVdnAAAAAAAAAB8WQTBEQ05VN2dRQk9ZVIR3WnZYTmFXZw
}基于 scroll 解决深度分页问题 原理上是对某次查询生成一个游标 scroll_id 后续的查询只需要根据这个游标去取数据直到结果集中返回的 hits 字段为空就表示遍历结束。 注意scroll_id 的生成可以理解为建立了一个临时的历史快照在此之后的增删改查等操作不会影响到这个快照的结果。 使用 curl 进行分页读取过程如下 先获取第一个 scroll_idurl 参数包括 /index/_type/ 和 scrollscroll 字段指定了scroll_id 的有效生存期以分钟为单位过期之后会被es 自动清理。如果文档不需要特定排序可以指定按照文档创建的时间返回会使迭代更高效。 GET /product/info/_search?scroll2m
{query:{match_all:{}},sort:[_doc]
}# 返回结果
{_scroll_id: DnF1ZXJ5VGhIbkXIdGNoAwAAAAAAAAAdFkEwRENOVTdnUUJPWVZUd1p2WE5hV2cAAAAAAAAAHhZBMERDTIU3Z1FCT1|WVHdadIhOYVdnAAAAAAAAAB8WQTBEQ05VN2dRQk9ZVIR3WnZYTmFXZw,took: 1,timed_out: false,_shards: {total: 1,successful: 1,failed: 0},hits:{...}
}后续的文档读取上一次查询返回的scroll_id 来不断的取下一页如果srcoll_id 的生存期很长那么每次返回的 scroll_id 都是一样的直到该 scroll_id 过期才会返回一个新的 scroll_id。请求指定的 scroll_id 时就不需要 /index/_type 等信息了。每读取一页都会重新设置 scroll_id 的生存时间所以这个时间只需要满足读取当前页就可以不需要满足读取所有的数据的时间1 分钟足以。 GET /product/info/_search?scrollDnF1ZXJ5VGhIbkXIdGNoAwAAAAAAAAAdFkEwRENOVTdnUUJPWVZUd1p2WE5hV2cAAAAAAAAAHhZBMERDTIU3Z1FCT1|WVHdadIhOYVdnAAAAAAAAAB8WQTBEQ05VN2dRQk9ZVIR3WnZYTmFXZw
{query:{match_all:{}},sort:[_doc]
}# 返回结果
{_scroll_id: DnF1ZXJ5VGhIbkXIdGNoAwAAAAAAAAAdFkEwRENOVTdnUUJPWVZUd1p2WE5hV2cAAAAAAAAAHhZBMERDTIU3Z1FCT1|WVHdadIhOYVdnAAAAAAAAAB8WQTBEQ05VN2dRQk9ZVIR3WnZYTmFXZw,took: 106,_shards: {total: 1,successful: 1,failed: 0},hits: {total: 22424,max_score: 1.0,hits: [{_index: product,_type: info,_id: did-519392_pdid-2010,_score: 1.0,_routing: 519392,_source: {....}}]}
}所有文档获取完毕之后需要手动清理掉 scroll_id 。虽然es 会有自动清理机制但是 srcoll_id 的存在会耗费大量的资源来保存一份当前查询结果集映像并且会占用文件描述符。所以用完之后要及时清理。使用 es 提供的 CLEAR_API 来删除指定的 scroll_id。 # 删掉指定的多个 srcoll_id
DELETE /_search/scroll -d
{scroll_id:[cXVlcnlBbmRGZXRjaDsxOzg3OTA4NDpTQzRmWWkwQ1Q1bUlwMjc0WmdIX2ZnOzA7]
}# 删除掉所有索引上的 scroll_id
DELETE /_search/scroll/_all# 查询当前所有的scroll 状态
GET /_nodes/stats/indices/_search?pretty# 返回结果
{cluster_name : 200.200.107.232,nodes : {SC4fYi0CT5mIp274ZgH_fg : {timestamp : 1514346295736,name : 200.200.107.232,transport_address : 200.200.107.232:9300,host : 200.200.107.232,ip : [ 200.200.107.232:9300, NONE ],indices : {search : {open_contexts : 0,query_total : 975758,query_time_in_millis : 329850,query_current : 0,fetch_total : 217069,fetch_time_in_millis : 84699,fetch_current : 0,scroll_total : 5348,scroll_time_in_millis : 92712468,scroll_current : 0}}}}
} 基于 search_after 实现深度分页 search_after 是 ES5.0 及之后版本提供的新特性search_after 有点类似 scroll但是和 scroll 又不一样它提供一个活动的游标通过上一次查询最后一条数据来进行下一次查询。 search_after 分页的方式和 scroll 有一些显著的区别首先它是根据上一页的最后一条数据来确定下一页的位置同时在分页请求的过程中如果有索引数据的增删改查这些变更也会实时的反映到游标上。 第一页的请求和正常的请求一样。 GET /order/info/_search
{size: 10,query: {match_all : {}},sort: [{date: asc}]
}# 返回结果
{_index: zmrecall,_type: recall,_id: 60310505115909,_score: null,_source: {...date: 1545037514},sort: [1545037514]}第二页的请求使用第一页返回结果的最后一个数据的值加上 search_after 字段来取下一页。注意使用 search_after 的时候要将 from 置为 0 或 -1。 curl -XGET 127.0.0.1:9200/order/info/_search
{size: 10,query: {match_all : {}},search_after: [1463538857], # 这个值与上次查询最后一条数据的sort值一致支持多个sort: [{date: asc}]
}注意 如果 search_after 中的关键字为654那么654323的文档也会被搜索到所以在选择 search_after 的排序字段时需要谨慎可以使用比如文档的id或者时间戳等。search_after 适用于深度分页 排序因为每一页的数据依赖于上一页最后一条数据所以无法跳页请求。返回的始终是最新的数据在分页过程中数据的位置可能会有变更。这种分页方式更加符合 moa 的业务场景。