MongoDb - “加入”集合[重复]

Posted

技术标签:

【中文标题】MongoDb - “加入”集合[重复]【英文标题】:MongoDb - "Join" Collections [duplicate] 【发布时间】:2018-04-11 23:16:38 【问题描述】:

给定以下集合:

消息收集

 
    "_id" : ObjectId("59f76fc3a8e87e411c22d0ac"),
    "OriginApp" : "App1", 
    "MsgGroupId" : "499", 
    "UserName" : "User1", 
    "Message" : "Test Message [Group ID: 499]"

 
    "_id" : ObjectId("59f76fc3a8e87e411c22d0ad"),
    "OriginApp" : "App1", 
    "MsgGroupId" : "499", 
    "UserName" : "User2", 
    "Message" : "Test Message [Group ID: 499]"

 
    "_id" : ObjectId("59f76fc3a8e87e411c22d0af"),
    "OriginApp" : "App1", 
    "MsgGroupId" : "499", 
    "UserName" : "User3", 
    "Message" : "Test Message [Group ID: 499]"

消息事件集合

 
    "_id" : ObjectId("59f772d1d22ea83b249d19c2"),
    "Event" : "Send", 
    "Msg" : 
        "UserName" : "User1", 
        "Metadata" : 
            "OriginApp" : "App1", 
            "MessageId" : "59f76fc3a8e87e411c22d0ac"
        , 
    , 
    "TimeStamp" : "2017-10-30T18:20:17Z"

 
    "_id" : ObjectId("59f772d1d22ea83b249d19c2"), 
    "Event" : "Open", 
    "Msg" : 
        "UserName" : "User1", 
        "Metadata" : 
            "OriginApp" : "App1", 
            "MessageId" : "59f76fc3a8e87e411c22d0ac"
        , 
    , 
    "TimeStamp" : "2017-10-30T18:30:16Z"

 
    "_id" : ObjectId("59f772d1d22ea83b249d19c2"), 
    "Event" : "Click", 
    "Msg" : 
        "UserName" : "User1", 
        "Metadata" : 
            "OriginApp" : "App1", 
            "MessageId" : "59f76fc3a8e87e411c22d0ac"
        , 
    , 
    "TimeStamp" : "2017-10-30T18:38:57Z"

我想返回如下所示的投影:

 
    "MessageId" : "59f76fc3a8e87e411c22d0ac" 
    "EventId" : "59f772d1d22ea83b249d19c2", 
    "Event" : "Send", 
    "UserName" : "User1", 
    "OriginApp" : "App1", 
    "TimeStamp" : "2017-10-30T18:20:17Z"

 
    "MessageId" : "59f76fc3a8e87e411c22d0ac" 
    "EventId" : "59f772d1d22ea83b249d19c2", 
    "Event" : "Open", 
    "UserName" : "User1", 
    "OriginApp" : "App1", 
    "TimeStamp" : "2017-10-30T18:30:16Z"

 
    "MessageId" : "59f76fc3a8e87e411c22d0ac" 
    "EventId" : "59f772d1d22ea83b249d19c2", 
    "Event" : "Click", 
    "UserName" : "User1", 
    "OriginApp" : "App1", 
    "TimeStamp" : "2017-10-30T18:38:57Z"

我马上就遇到了问题,因为 MsgEvent.Msg.Metadata.MessageId 是一个字符串,而 Message._id 是一个 ObjectId。不可能将 MsgEvent.Msg.Metadata.MessageId 创建为 ObjectId,因为它由外部应用程序作为简单的 json 返回给服务。

有没有办法使用 distinct 运算符或某种类型的聚合来实现所需的结果?

-- 更新--

鉴于 MongoDb 不允许在查询中进行数据转换(这是原始问题的一部分),我现在通过提供一个作为字符串的 Guid 附加属性解决了这个问题:

消息收集

 
    "_id" : ObjectId("59f76fc3a8e87e411c22d0ac"),
    "GuidString" : "d273a5dd-7291-432f-a9ab-8bad7343a1a4",
    "OriginApp" : "App1", 
    "MsgGroupId" : "499", 
    "UserName" : "User1", 
    "Message" : "Test Message [Group ID: 499]"

消息事件集合

 
    "_id" : ObjectId("59f772d1d22ea83b249d19c2"),
    "Event" : "Send", 
    "Msg" : 
        "UserName" : "User1", 
        "Metadata" : 
            "OriginApp" : "App1", 
            "MessageId" : "59f76fc3a8e87e411c22d0ac",
            GuidString" : "d273a5dd-7291-432f-a9ab-8bad7343a1a4"
        , 
    , 
    "TimeStamp" : "2017-10-30T18:20:17Z"

等等……

以下聚合将返回预期结果:

db.MessageEvent.aggregate(
[
 $match :  "Msg.Metadata.GuidString" : "d273a5dd-7291-432f-a9ab-8bad7343a1a4"  ,
 $unwind: "$Msg" ,

   $lookup: 
    "from": "GuidString",
    "localField": "ChannelSenderId",
    "foreignField": "GuidString",
    "as": "messages"
   

]);

【问题讨论】:

***.com/questions/68155715/… 【参考方案1】:

合并多个集合或对数据进行任何重塑(例如分组、取消分组(展开))的唯一方法是使用聚合框架(推荐)或旧的 map reduce 框架(不推荐)。

具体来说,在聚合时,您可以选择各种聚合步骤,包括 $lookup。

从简要查看您的数据来看,您需要聚合 MessageEvent 集合并在 Message 集合中查找数据(因为 ID 从 MessageEvent 指向 Message 对象,反之亦然)。

您有 $project, $group 阶段可以帮助您重塑数据。

【讨论】:

以上是关于MongoDb - “加入”集合[重复]的主要内容,如果未能解决你的问题,请参考以下文章

MongoDb - “加入”集合[重复]

MongoDB和“加入”[重复]

如何从restapi中删除mongodb集合[重复]

MongoDB/Mongoose 一对多,在子节点中引用父节点 - 分组并加入

如何删除 MongoDb 中的重复项?

mongo的碎片整理