【问题标题】:Find and Count elements of collection with Mongoose使用 Mongoose 查找和计数集合元素
【发布时间】:2016-05-28 09:31:35
【问题描述】:

在 Mongoose 中,我需要在集合中查找元素并对其进行计数,并同时获取查找和计数的结果。我试过了

Model.find().count(function (err, count) {
    // Get count, but cannot get results of find
});

有没有办法在不调用两次的情况下同时获取 find() 和 count()?

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    可以使用返回数组的长度:

    Model.find().exec(function (err, results) {
      var count = results.length
    
    });
    

    【讨论】:

    • 这里.exec的目的是什么?
    • 这只是一种编码风格,你可以这样写:Model.find({}, function(err, results) {}),检查这个:mongoosejs.com/docs/api.html#model_Model.find
    • @MarcB 虽然这不是最好的解释,但这在技术上是正确的,并且比您目前接受的答案更有效。这是猫鼬通过“自动”将结果转换为“数组”来处理结果光标的方式的产物。因此,合乎逻辑的做法是将数组“长度”作为“计数”返回。这避免了做两次。只有当您想将“光标”直接用作“流”时,才需要运行单独的计数。但这可以说是在流处理中处理的。
    • @BlakesSeven 对不起,我实际上是在评论原始答案。我想这真的取决于您希望如何使用“计数”。我在这里做了几个假设。我考虑了 webapp 上下文中的实际实现以及为什么需要计数。这可能是您希望向用户展示的内容:“显示 32{results.length} 结果:”后跟结果列表。但是,如果数据集达到数千个条目怎么办。你需要这样的东西:'显示 4331 个结果中的 50 个结果 {results.length === 50}'。
    • @user1695032 没错,但关键是“大响应”对于会导致数组的调用语法来说是脱离上下文的。这不是给出的答案,但我确实在评论中为“大结果”添加了“流”上下文(以添加该值)。是的,您也可以“流式传输”JSON 编写器输出。因此,在不使用 .count() 作为附加调用的情况下,大结果中的计数是有效的。只有在“分页”时才需要它。当你当然应该总是使用两个查询时。一个用于完整计数,另一个用于当前页面。
    【解决方案2】:

    很遗憾,您必须执行 2 个单独的查询。 Festo 的答案只有在数据库中的元素少于限制时才有效。

    var countQuery = Model.count();
    var findQuery = Model.find().limit(2);
    
    countQuery.exec(function (e, count) {
      console.log('count', count); // can be more than 2, this is not calculated, mongo stores this value internally
    })
    findQuery.exec(function(e, data) {
      console.log('found items', data); // will be 2 or less elements
    });
    

    【讨论】:

    • 你能解释一下你所说的极限是什么意思吗?
    • 想象一下,如果您的数据库中有 1000 个条目。你不想一次得到它们。我认为猫鼬也设置了某种默认限制。您想知道计数(在本例中为 1000),但可能只返回 50 个结果。如果您尝试计算响应的长度,您将得到 50。
    • 此外,如果您想向用户显示结果并进行分页,您将使用限制。因此,如果每个页面有 50 个响应,您的第三页结果可能会这样查询:query.skip(100).limit(50) 您跳过前 2x50 并显示第三批 50 个结果。
    【解决方案3】:

    正如猫鼬文档和本杰明的回答中所述,不推荐使用 Model.count() 方法。替代使用 count() 的方法如下:

      SomeModel.countDocuments({}, function(err, count) {
        if (err) { return handleError(err) } //handle possible errors
        console.log(count)
        //and do some other fancy stuff
    })
    

    SomeModel
    .estimatedDocumentCount()
    .then(count => {
        console.log(count)
        //and do one super neat trick
    })
    .catch(err => {
        //handle possible errors
    })
    

    【讨论】:

      【解决方案4】:

      您也可以使用mongoose-paginate plugin

      例如:

      Model.paginate({}, { offset: 100, limit: 0 }).then(function(result) {
            // result.docs - Array of documents
            // result.total - Total number of documents in collection that match a query
            // result.limit - 0
            // result.offset - 100
      });
      

      【讨论】:

        【解决方案5】:

        DeprecationWarning:collection.count 已弃用,将在未来版本中删除。请改用 Collection.countDocuments 或 Collection.estimatedDocumentCount。 希望此更新对某人有所帮助。 示例:

        var user = await User.find().countDocuments()

        【讨论】:

          猜你喜欢
          • 2017-12-05
          • 2019-04-19
          • 1970-01-01
          • 2020-08-16
          • 1970-01-01
          • 2020-12-20
          • 2014-05-21
          • 1970-01-01
          • 2020-07-08
          相关资源
          最近更新 更多