elasticsearch.js中pagination和scro

2018-05-29  本文已影响0人  詹小云

使用elasticsearch去做翻页功能的时候,会考虑到两种实现方法:如题中的pagination和scroll。

pagination

假设我们要拿头十条数据

//from:开始拿数据的索引值,默认值为0
//size:获取的数据量,默认值为10条
client.search({
    index:index,
    type:type,
    from:0,
    size:10
},(res)=>{
    console.log(res.hits.hits)
})

官网文档里有这么一句话:

Results are sorted before being returned.

我猜测这句话表明了每次获取的数据都是实时的,经验证,我的猜测是成立的。
但是这种实时用于移动端上拉加载时,就会出现以下弊端
1.插入情景
假设第一页获取了10条数据
而在你准备获取第二页前,有人插入了1条数据
此时你再从11开始拿数据就会重复拿到第一页的第10条
2.删除情景
一样假设第一页获取了10条数据
而在你准备获取第二页前,有人删除了第一页1条数据
此时你再从11开始拿数据就会漏掉原本在第二页的第一条数据

elasticsearch是采用分布式存储的。现在我们假设这个index中存在5个碎片,若是要从这个index中拿取10条数据,就需要在每个碎片中拿取头10条数据,然后在这50条数据中再排序选取头十条。

pagination 获取数据示例图
可想而知,在分布式系统中,数据量越大,排序成本越大。所以官网建议:每次搜索的数据量最好不要超过1000条

小结:pagination比较适合用于pc端的分页

scroll

假设我们要拿到所有title为test的数据

//scroll:scroll_id存活时长
var allTitles = [];
client.search({
    index:index,
    type:type,
    scroll:'30s',
    q: 'title:test'
},function getMoreUntilDone(error, response)=>{
    response.hits.hits.forEach(function (hit) {
        allTitles.push(hit.fields.title);
    });
    //直到拿到所有title为test的数据,才停止scroll
    if (response.hits.total !== allTitles.length) {
        client.scroll({
        scrollId: response._scroll_id,
        scroll: '30s'
        }, getMoreUntilDone);
    } else {
        console.log('every "test" title', allTitles);
    }
})

scroll的出现是为了解决逐步加载大量数据这个功能点,所以并不具备实时性。数据映射会在初始化search的时候完成。所以在scroll_id失效之前(或重新初始化search)之前,别人的修改对你获取的数据不会生效。

小结:scroll比较适合用于移动端的下拉加载,虽然scroll_id具有存活时长,但是在失效时,可以重新获取。

写在最后
pagination文档scroll文档scroll例子

上一篇 下一篇

猜你喜欢

热点阅读