【问题标题】:MongoDB: Filter using data from multiple collectionsMongoDB:使用来自多个集合的数据进行过滤
【发布时间】:2017-11-11 15:22:44
【问题描述】:

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

用户

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

【问题讨论】:

  • 通过查找聚合或在应用程序级别。 mapreduce 仅适用于单个集合,因此需要一个临时集合来进行查找,这几乎不适合操作查询。
  • 你能提供一个使用查找聚合的例子吗?您将如何在应用程序级别上解决这个问题?你的意思是请求数据,然后手动合并?
  • docs.mongodb.com/manual/reference/operator/aggregation/lookup,如果您遇到任何特殊问题,请随时询问。使用应用层 - 是的。从事件中获取所有匹配的用户 id(同样使用聚合,但不查找),然后按 id 获取用户。

标签: mongodb schema aggregation-framework


【解决方案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}
            }
        },

    ]



);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多