我有两个收藏。 “用户”集合和“事件”集合。事件集合上有一个主键,用于指示事件属于哪个用户。
我想计算用户符合特定条件的事件数。
当前,我正在执行以下操作:
db.users.find({ usersMatchingACondition }).forEach(user => {
const eventCount = db.events.find({
title: 'An event title that I want to find',
userId: user._id
}).count();
print(`This user has ${eventCount} events`);
});
理想情况下,我想返回的是具有UserID的数组或对象以及该用户具有多少事件。
拥有10,000个用户-显然会产生10,000个查询,我认为它可以提高效率!
我认为使用某种汇总查询很容易-但是我对语法不熟悉,并且正在努力将其包裹住。
任何帮助将不胜感激!
答案 0 :(得分:2)
您需要$lookup才能从events
匹配的user_id
中获取数据。然后,您可以使用$filter来应用事件级条件并获得计数,您可以使用$size运算符
db.users.aggregate([
{
$match: { //users matching condition }
},
{
$lookup:
{
from: 'events',
localField: '_id', //your "primary key"
foreignField: 'user_id',
as: 'user_events'
}
},
{
$addFields: {
user_events: {
$filter: {
input: "$user_events",
cond: {
$eq: [
'$$this.title', 'An event title that I want to find'
]
}
}
}
}
},
{
$project: {
_id: 1,
// other fields you want to retrieve: 1,
totalEvents: { $size: "$user_events" }
}
}
])
答案 1 :(得分:0)
没有聚合就无法完成很多优化,但是由于您是专门说的
首先,而不是
const eventCount = db.events.find({
title: 'An event title that I want to find',
userId: user._id
}).count();
做
const eventCount = db.events.count({
title: 'An event title that I want to find',
userId: user._id
});
这将大大加快您的查询速度,因为查找查询实际上首先会获取文档,然后进行计数。
要返回数组,您只需在开始处初始化一个数组,然后将{userid:id,count:eventCount}个对象推入该数组即可。