MongoDb - "Join" 合集
MongoDb - "Join" Collections
给定以下集合:
留言合集
{
"_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"
}
我想要 return 如下所示的投影:
{
"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。不可能将 create MsgEvent.Msg.Metadata.MessageId 作为 ObjectId,因为它由外部应用程序 return 编辑到服务,就像 json 一样简单。
有没有办法使用不同的运算符或某种类型的聚合来实现所需的结果?
--更新--
鉴于 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"
}
等...
以下聚合将 return 预期结果:
db.MessageEvent.aggregate(
[
{ $match : { "Msg.Metadata.GuidString" : "d273a5dd-7291-432f-a9ab-8bad7343a1a4" } },
{ $unwind: "$Msg" },
{
$lookup: {
"from": "GuidString",
"localField": "ChannelSenderId",
"foreignField": "GuidString",
"as": "messages"
}
}
]);
合并多个集合或对数据进行任何重塑(例如分组、取消分组(unwind))的唯一方法是使用聚合框架(推荐)或旧的 map reduce 框架(不推荐)。
具体来说,在聚合时,您可以选择各种聚合步骤,包括 $lookup。
通过简要查看您的数据,您需要聚合 MessageEvent 集合和 Message 集合中的查找数据(因为 ID 从 MessageEvent 指向 Message 对象,反之亦然)。
您有 $project、$group 阶段可以帮助您重塑数据。
给定以下集合:
留言合集
{
"_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"
}
我想要 return 如下所示的投影:
{
"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。不可能将 create MsgEvent.Msg.Metadata.MessageId 作为 ObjectId,因为它由外部应用程序 return 编辑到服务,就像 json 一样简单。
有没有办法使用不同的运算符或某种类型的聚合来实现所需的结果?
--更新--
鉴于 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"
}
等...
以下聚合将 return 预期结果:
db.MessageEvent.aggregate(
[
{ $match : { "Msg.Metadata.GuidString" : "d273a5dd-7291-432f-a9ab-8bad7343a1a4" } },
{ $unwind: "$Msg" },
{
$lookup: {
"from": "GuidString",
"localField": "ChannelSenderId",
"foreignField": "GuidString",
"as": "messages"
}
}
]);
合并多个集合或对数据进行任何重塑(例如分组、取消分组(unwind))的唯一方法是使用聚合框架(推荐)或旧的 map reduce 框架(不推荐)。
具体来说,在聚合时,您可以选择各种聚合步骤,包括 $lookup。
通过简要查看您的数据,您需要聚合 MessageEvent 集合和 Message 集合中的查找数据(因为 ID 从 MessageEvent 指向 Message 对象,反之亦然)。
您有 $project、$group 阶段可以帮助您重塑数据。