美文网首页
elasticsearch.js中pagination和scro

elasticsearch.js中pagination和scro

作者: 詹小云 | 来源:发表于2018-05-29 13:55 被阅读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例子

    相关文章

      网友评论

          本文标题:elasticsearch.js中pagination和scro

          本文链接:https://www.haomeiwen.com/subject/ejmgjftx.html