node.js - Node js + Mongodb 更好的方法来选择特定文档的数量
问题描述
选择用户数量的更好方法是什么
如果用户数量增加,JavaScript 过滤代码会正常工作吗?
使用多个 mongodb 请求
const db = fastify.mongo.db; const users_collection = await db.collection('users'); let users = { registered: { count: null, typed_count: { vk: null, ok: null, google: null, oneclick: null, }, }, }; users.registered.count = await users_collection.countDocuments(); users.registered.typed_count.vk = await users_collection.countDocuments({ 'social.vk': { $exists: true } }); users.registered.typed_count.ok = await users_collection.countDocuments({ 'social.ok': { $exists: true } }); users.registered.typed_count.google = await users_collection.countDocuments({ 'social.google': { $exists: true } }); users.registered.typed_count.oneclick = await users_collection.countDocuments({ social: { $exists: false } });
使用一个 mongodb 请求和 javascript 过滤
const db = fastify.mongo.db; const users_collection = await db.collection('users'); let users = { registered: { count: null, typed_count: { vk: null, ok: null, google: null, oneclick: null, }, }, }; const data = await (await users_collection.find()).toArray(); users.registered.count = data.length; users.registered.typed_count.vk = data.filter((obj) => obj.social && obj.social.vk).length; users.registered.typed_count.ok = data.filter((obj) => obj.social && obj.social.ok).length; users.registered.typed_count.google = data.filter((obj) => obj.social && obj.social.google).length; users.registered.typed_count.oneclick = data.filter((obj) => !obj.social).length;
解决方案
第一种方法将花费更多时间,因为涉及的人数过多network requests
,并且
第二种方法将占用您太多的时间,server's memory (RAM)
因为所有文档都将首先被带入内存。
所以我们可以通过使用 MongoDB 管道来减少时间和内存aggregation's
$group
,看起来像这样
db.collection.aggregate([
{
$group: {
_id: null,
vk: {
$sum: {
$cond: [{ $gt: ["$social.vk", null]}, 1, 0]
}
},
ok: {
$sum: {
$cond: [{ $gt: ["$social.ok", null]}, 1, 0]
}
},
google: {
$sum: {
$cond: [{ $gt: ["$social.google", null]}, 1, 0]
}
},
oneclick: {
$sum: {
$cond: [{ $lte: ["$social", null]}, 1, 0]
}
},
}
}
])
推荐阅读
- swift - Swift5 文本字段的几种输入法(PickerView & System字母键盘)同时进行
- javascript - AWS Amplify 错误从 aws-amplify 导入 StorageProvider 类
- sql - 如何有效地对复杂 SQL 查询的结果进行分页?
- c# - 我如何连接电子邮件地址?C#
- java - 在应用程序类中使用静态接口是否安全?
- c++ - 通过槽和信号在不同线程中的两个qt对象之间进行通信
- azure - 想要从 Microsoft Office 365 管理 API 获取用户
- angular - 在 ng build prod 之后我无法使用我的 rest api
- java - 保存到流管道中的数据库
- jgit - 使用 JGit 检索文件的特定版本