我有一个应用程序以事件的形式存储用户及其行为。有两个集合,一个用于用户,一个用于事件。文件如下:
用户
{
"_id" : ObjectId("593aa71e2f9d5140000bb44e"),
"name" : "Antonette Ortiz",
"country" : "France"
}
事件
{
"_id" : ObjectId("593aaa84c685604066a6a0cf"),
"name" : "message_sent",
"timestamp" : ISODate("2016-11-01T04:39:52.667Z"),
"user" : ObjectId("593aa728d135484002399bac"),
"attributes" : {
"str" : "plum",
"int" : 82
}
}
现在我希望能够不仅通过其属性获取用户列表,而且还能够获取他们触发的事件以及特定时间范围内的用户列表。
示例查询类似于:“来自法国的所有用户在过去7天内至少发送了3封邮件”。
我如何使用MongoDB实现这一点,同样在性能方面(例如我有几百万个事件)?这只是两个集合甚至可能,或者我必须使用聚合/地图减少?如果是这样,您会建议如何更改架构?
答案 0 :(得分:1)
根据MongoDB文档
$ lookup阶段在一个字段之间进行相等匹配 从“已加入”的文档中输入带有字段的文档 集合。
例如
“来自法国的所有用户在过去7天内至少发送了3封邮件”。
要检索上述条件的数据,其聚合查询将如下
db.Event.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
name:'message_sent',
timestamp:{$gte:ISODate("2016-10-25T04:39:52.667+0000"),$lte:ISODate("2016-11-01T04:39:52.667+0000")}
}
},
// Stage 2
{
$group: {
_id:{user:'$user'},
counter:{$sum:1}
}
},
// Stage 3
{
$lookup: {
"from" : "User",
"localField" : "_id.user",
"foreignField" : "_id",
"as" : "user"
}
},
// Stage 4
{
$match: {
'user.country':'France' ,
counter:{$gte:3}
}
},
]
);