MongoDB:使用来自多个集合的数据进行过滤

时间:2017-06-09 14:43:00

标签: mongodb schema aggregation-framework

我有一个应用程序以事件的形式存储用户及其行为。有两个集合,一个用于用户,一个用于事件。文件如下:

用户

{
    "_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实现这一点,同样在性能方面(例如我有几百万个事件)?这只是两个集合甚至可能,或者我必须使用聚合/地图减少?如果是这样,您会建议如何更改架构?

1 个答案:

答案 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}
            }
        },

    ]



);