使用 Mongoose 查找和计数集合元素
Posted
技术标签:
【中文标题】使用 Mongoose 查找和计数集合元素【英文标题】:Find and Count elements of collection with Mongoose 【发布时间】:2016-05-28 09:31:35 【问题描述】:在 Mongoose 中,我需要在集合中查找元素并对其进行计数,并同时获取查找和计数的结果。我试过了
Model.find().count(function (err, count)
// Get count, but cannot get results of find
);
有没有办法在不调用两次的情况下同时获取 find() 和 count()?
【问题讨论】:
【参考方案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 上下文中的实际实现以及为什么需要计数。这可能是您希望向用户展示的内容:“显示 32results.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()
【讨论】:
以上是关于使用 Mongoose 查找和计数集合元素的主要内容,如果未能解决你的问题,请参考以下文章