【问题标题】:Infinite scroll with Angularjs and Mongoose - performance使用 Angularjs 和 Mongoose 进行无限滚动 - 性能
【发布时间】:2015-03-07 20:54:54
【问题描述】:

我有一个使用 Angular 使用 $http.get() 从 MongoDB 使用 Mongoose 和 Expressjs 获得的图像列表。

我所做的工作正常,但我对性能有疑问。

到目前为止,我找到了两种方法:

  • 使用skip
  • 使用$nin

查询如下所示:

    // Using $nin:
    var skip = req.query.skip || [];

    User.find({ _id : { $nin: skip }})
    .sort({ _id: -1 })
    .limit(15)
    .exec(function(err, users) {
    if (err) res.json({ 'msg': 'Error loading users' });
    res.json({
      users: users
    });
  });

和:

    // Using skip
    User.find({})
    .sort({ _id: -1 })
    .skip(15)
    .limit(15)
    .exec(function(err, users) {
    if (err) res.json({ 'msg': 'Error loading users' });
    res.json({
      users: users
    });
  });

谷歌搜索似乎使用skip 一段时间后缺乏性能......

但是查看$nin 选项,我在滚动和滚动一个很长的查询后发现...有很多_id...

这两种解决方案哪个更好用?

或者有比那些更好的第三种方法,也许我做错了什么?

谢谢

【问题讨论】:

  • 您还可以使用lean() 选项来减少猫鼬使用其所有方法等构建模型所需的时间。IMO skip 选项在这里更好(这就是我实现分页的方式解决方案,从未遇到任何问题)
  • 您能告诉我更多关于lean() 的信息并写一个工作示例吗? lean() 的文档缺少各种信息。谢谢。
  • lean 选项告诉 mongoose 不要将它的方法包含在结果中,因此您将无法在将获得的结果上使用 mongoose。你可以像这样使用它:User.find({}).sort({ _id: -1 }).skip(15).limit(15).lean().exec(...)。它将减少从 db 获取结果所需的时间,并且几乎与本机 mongo 客户端一样快
  • @VsevolodGoloviznin .lean() 与此无关。请不要误导 cmets。
  • 使用.skip(15).limit(15) 似乎不能正常工作...我总是看到重复。

标签: javascript node.js mongodb mongoose mongodb-query


【解决方案1】:

理想情况下,您希望将$nin 与以前看到的_id 值列表一起使用,但将其与$gte$lte(取决于顺序)运算符结合在您要排序的内容上。

这通常是大多数“其他排序的查询”的情况,但如果_id 字段是您要排序的字段(并且按降序排列),则只需使用$lt查找小于上一页中“最后看到的值”的值。

因此,在迭代时,将最后一项的“最后看到的值”存储在“页面限制”结果中,然后在后续查询中使用 $lt 运算符:

即:

var lastSeen = null; // declare in a global or session or something

User.find({})
    .sort({ "_id": -1 })
    .limit(15)
    .exec(function(err,docs) {
        lastSeen = docs.slice(-1).id;
    });

然后:

User.find({ "_id": { "$lt": lastSeen })
    .sort({ "_id": -1 })
    .limit(15)
    .exec(function(err,docs) {
        lastSeen = docs.slice(-1).id;
    });

【讨论】:

  • Angular 发送到服务器的无限查询怎么样?
  • 什么是“无限查询”?此处为“单个” lastSeen 值中的简单参数,即显示的列表中的“最后一个”。 1-5 -> 然后( > 5 ) = 6 - 10 -> 然后 ( > 10 ) = 10 - 15 等等。不难。
  • 不难,但我是一个试图学习的菜鸟...实现此代码我一开始没有收到任何数据...
  • @AyeyeBrazo 慢一点。 “一开始就没有数据”?查询对象一开始是空白的。因此,您检索所有内容,并在反向排序后限制为 15 个结果。在某个地方,即使是在服务器端或客户端,您也需要注意在这些结果中看到的最后一个 _id 值。然后在您的“getMoreResults”调用中,您希望将该值传递给查询。由于您是反向排序,因此您使用 $lt (或“小于”)运算符,如图所示。这是“前向寻呼”的基本概念。根据上次看到的下一个最高值检索的位置。
  • 知道了。谢谢它运行良好,我希望它在性能方面能够处理大量数据。
猜你喜欢
  • 1970-01-01
  • 2014-05-17
  • 2015-06-03
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 2021-07-20
  • 2017-08-14
相关资源
最近更新 更多