我一直将 MongoDB 与 node.js
和 mongoose
库一起使用。我决定开始使用 MongoDB,因为我到处都发现它是 node.js
应用程序的最佳解决方案。
虽然我的 API 的响应时间很好,但我不确定 MongoDB 在扩展时是否能够处理它。
我注意到我的大多数查询不足以获取我需要的所有数据,因此我依赖于创建多个查询并使用一些 javascript map/reduce 函数(这就是我所担心的)。
看这个例子:
User
.find({
idol : true
})
.sort({
'metas.followers' : -1
})
.select('-password -__v -posts -email')
.skip(offset)
.limit(30)
.exec(function(err, retData)
{
promisedIdols = retData.map(function(idol)
{
return idol.withStatistics(Post, Follow, req.user);
});
idols = [];
if(promisedIdols.length == 0)
{
callback();
}
for(var i=0; i<promisedIdols.length; i++)
{
promisedIdols[i].delegate(function(result)
{
idols.push(result);
if(idols.length == promisedIdols.length)
{
callback();
}
});
}
});
我使用了 map
来收集 promises
数组,这些 promise 将在运行以下代码后得到解决:
var obj = this.toObject();
var deferred = new Promise();
Post
.find({ idol : obj._id })
.lean()
.exec(function(err, posts)
{
var postViews = 0;
var postLikes = 0;
var postShares = 0;
posts.reduce(function(prev, next)
{
postViews += next.views.length;
postLikes += next.likes.length;
postShares += next.shares.length;
}, 0);
obj.metas.postViews = postViews;
obj.metas.postLikes = postLikes;
obj.metas.postShares = postShares;
obj.metas.postCount = posts.length;
Subscription
.count({ idol : obj._id }, function(err, count)
{
obj.metas.subscribers = count;
deferred.deliver(obj);
});
});
使用reduce
函数。
我看不出这段代码在大规模上运行良好。也许我应该重组我的数据库?也许我应该更改我的数据库系统?也许我错误地使用了 MongoDB?
专家?
谢谢。
最佳答案
如果你设置了一个好的数据模型,Mongo 可以处理很多事情。当您想要扩展时,需要记住一些事情。
尽量避免对数据进行过多标准化,并将其拆分为不同的集合。 数据重复是(有时,如果使用得当的话)你的 friend ,它将帮助你进行更简单的查询,立即填充。是的,这可能意味着当你更新数据时,你必须在两个地方更新,但如果你异步执行(无论是否 promise ),Mongo 可以接受大量写入。
对于您的特定查询,我没有看到完整的数据模型,但也许您可以使用聚合框架。该管道是原生的(C++,与 mapReduce JavaScript 不同)并且运行速度非常快。
类似于:
db.post.aggregate(
// First $match to reduce the dataset
{
$match: {idol : obj._id}
},
// then group and aggregate your data
{
$group: {
_id: '$idol', // group by that idol thing
postViews: {$sum: '$postViews'},
postLikes: {$sum: '$postLikes'}
},
},
// Then use project to arrange the result the way you like it
{
$project: {
_id: false, //or true if you need it
metas: {
postViews: '$postViews'
},
likeCountOfPosts: '$postLikes', // that's how you'd rename
whatIsIt: {$literal: 'a great post'}
}
}
);
您还可以执行大量条件操作、分组、排序、缠绕和展开、混合和打乱管道。
它比 Mongo mapReduce 快得多。
关于javascript - Mongo 会处理我的服务吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28133345/