简体   繁体   English

如何使用查找也通过查找出现的数据?

[英]How to use lookup for data which appear by lookup too?

db.getCollection('alert_service_alert').aggregate(
[{"$addFields":{"uuid":"$_id"}},{"$project":{"_id":0}},


{"$lookup":{
    "from":"alert_service_notification",
    "localField":"notifications",
    "foreignField":"_id",
    "as":"notifications"
    }
},       

{"$sort":{"created":-1}},{"$limit":30}]
)

and in response I had expect result作为回应,我期待结果

"uuid" : "64e21d83-6f2f-4d70-aeaa-b431e936bb54",
"alert_name" : "novemberAlert",
"notifications" : [ 
    {
        "_id" : "8be1e36d-495d-476b-b033-1618d01ee93e",
        "notification_name" : "novembernotification",
        "rule" : {
            "0" : {
                "rule_name" : "period",
                "rule_value" : 3600
            }
        },
        "search_tags" : [ 
            "period"
        ],
        "group_recipients" : [ 
            "7accb3f3-0fc1-4f23-b349-e7832fa99832"
        ],
        "created" : ISODate("2021-11-18T03:30:01.307Z"),
        "updated" : ISODate("2021-11-18T03:30:01.307Z"),
        "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
        "updated_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
        "recipient_list" : [ 
            "a98888a2-e347-4d26-92df-aed8ce4916a9"
        ]
    }
],

the I decided add group_recipients from notification to response like that我决定将 group_recipients 从通知添加到响应中

db.getCollection('alert_service_alert').aggregate(
[{"$addFields":{"uuid":"$_id"}},{"$project":{"_id":0}},


{"$lookup":{
    "from":"alert_service_notification",
    "localField":"notifications",
    "foreignField":"_id",
    "as":"notifications"
    }
},

{"$lookup":
    {
        "from":"alert_service_group_recipients",
        "localField":"notifications.group_recipients",
        "foreignField":"_id",
        "as":"group_recipients"
    }
},
   
{"$sort":{"created":-1}},{"$limit":30}]
)

but I faced with strange behavour, group_recipients field on the top level with alert name, but should be in notifications field, it looks like lookup in lookup但我遇到了奇怪的行为,顶级的 group_recipients 字段带有警报名称,但应该在通知字段中,它看起来像查找中的查找

"uuid" : "64e21d83-6f2f-4d70-aeaa-b431e936bb54",
"alert_name" : "novemberAlert",
"notifications" : [ 
    {
        "_id" : "8be1e36d-495d-476b-b033-1618d01ee93e",
        "notification_name" : "novembernotification",
        "rule" : {
            "0" : {
                "rule_name" : "period",
                "rule_value" : 3600
            }
        },
        "search_tags" : [ 
            "period"
        ],
        "group_recipients" : [ 
            "7accb3f3-0fc1-4f23-b349-e7832fa99832"
        ],
        "created" : ISODate("2021-11-18T03:30:01.307Z"),
        "updated" : ISODate("2021-11-18T03:30:01.307Z"),
        "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
        "updated_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
        "recipient_list" : [ 
            "a98888a2-e347-4d26-92df-aed8ce4916a9"
        ]
    }
],
"group_recipients" : [ 
    {
        "_id" : "7accb3f3-0fc1-4f23-b349-e7832fa99832",
        "group_name" : "my_sh_group",
        "channels" : [ 
            {
                "channel_name" : "email",
                "receiver_identity" : "s@s.com"
            }, 
            {
                "channel_name" : "slack",
                "receiver_identity" : "ideas"
            }, 
            {
                "channel_name" : "telegram",
                "receiver_identity" : "-686779898_match"
            }
        ],
        "created" : ISODate("2021-11-18T03:28:18.823Z"),
        "updated" : ISODate("2021-11-18T03:28:18.823Z"),
        "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
        "updated_by" : null
    }
]

when I changed lookup like that当我像那样改变查找时

db.getCollection('alert_service_alert').aggregate(
[{"$addFields":{"uuid":"$_id"}},{"$project":{"_id":0}},


{"$lookup":{
    "from":"alert_service_notification",
    "localField":"notifications",
    "foreignField":"_id",
    "as":"notifications"
    }
},

{"$lookup":
    {
        "from":"alert_service_group_recipients",
        "localField":"notifications.group_recipients",
        "foreignField":"_id",
        "as":"notifications.group_recipients"
    }
},



{"$sort":{"created":-1}},{"$limit":30}]
)

I faced with case when notifications array was absolutelly replaced to我遇到了通知数组被完全替换为的情况

"uuid" : "64e21d83-6f2f-4d70-aeaa-b431e936bb54",
"alert_name" : "novemberAlert",
"notifications" : {
    "group_recipients" : [ 
        {
            "_id" : "7accb3f3-0fc1-4f23-b349-e7832fa99832",
            "group_name" : "my_sh_group",
            "channels" : [ 
                {
                    "channel_name" : "email",
                    "receiver_identity" : "s@s.com"
                }, 
                {
                    "channel_name" : "slack",
                    "receiver_identity" : "ideas"
                }, 
                {
                    "channel_name" : "telegram",
                    "receiver_identity" : "-686779898_match"
                }
            ],
            "created" : ISODate("2021-11-18T03:28:18.823Z"),
            "updated" : ISODate("2021-11-18T03:28:18.823Z"),
            "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
            "updated_by" : null
        }
    ]
},

where is lost other data about notifications?关于通知的其他数据丢失在哪里?

UPDATE更新

I provided logic like that我提供了这样的逻辑

db.getCollection('alert_service_alert').aggregate(
[{"$addFields":{"uuid":"$_id"}},{"$project":{"_id":0}},


{"$lookup":{
    "from":"alert_service_notification",
    "localField":"notifications",
    "foreignField":"_id",
    "as":"notifications"
    }
},

{"$lookup":
    {
        "from":"alert_service_group_recipients",
        "localField":"notifications.group_recipients",
        "foreignField":"_id",
        "as":"group_recipients"
    }
},
{ "$addFields": { "notifications.group_recipients": "$group_recipients" }},
{"$sort":{"created":-1}},{"$limit":30}]
)
enter code here

and I added new one notification to my alert with one group_recipients, so shuld be one notification with two groups and one notification with one group, but in that case first notification should has two group_recipients record and second should has one, but by some reason each notification has three,我向我的警报添加了一个新的通知,其中包含一个 group_recipients,因此应该是一个包含两个组的通知和一个包含一个组的通知,但在这种情况下,第一个通知应该有两个 group_recipients 记录,第二个应该有一个,但由于某种原因每个通知有三个,

"uuid" : "64e21d83-6f2f-4d70-aeaa-b431e936bb54",
"alert_name" : "novemberAlert",
 "notifications" : [ 
        {
            "_id" : "8be1e36d-495d-476b-b033-1618d01ee93e",
            "notification_name" : "novembernotification",
            "rule" : {
                "0" : {
                    "rule_name" : "period",
                    "rule_value" : 3600
                }
            },
            "search_tags" : [ 
                "period"
            ],
            "group_recipients" : [ 
                {
                    "_id" : "32d09a03-1ff0-422c-9de6-6df09aeeb519",
                    "group_name" : "my_sh_group",
                    "channels" : [ 
                        {
                            "channel_name" : "telegram",
                            "receiver_identity" : "novembersh"
                        }
                    ],
                    "created" : ISODate("2021-11-18T03:27:58.424Z"),
                    "updated" : ISODate("2021-11-18T03:27:58.424Z"),
                    "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
                    "updated_by" : null
                }, 
                {
                    "_id" : "7accb3f3-0fc1-4f23-b349-e7832fa99832",
                    "group_name" : "my_sh_group",
                    "channels" : [ 
                        {
                            "channel_name" : "email",
                            "receiver_identity" : "s@s.com"
                        }, 
                        {
                            "channel_name" : "slack",
                            "receiver_identity" : "ideas"
                        }, 
                        {
                            "channel_name" : "telegram",
                            "receiver_identity" : "-686779898_match"
                        }
                    ],
                    "created" : ISODate("2021-11-18T03:28:18.823Z"),
                    "updated" : ISODate("2021-11-18T03:28:18.823Z"),
                    "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
                    "updated_by" : null
                }, 
                {
                    "_id" : "d5789011-0bae-4bd5-9acf-eb5af8f04813",
                    "group_name" : "admins",
                    "channels" : [ 
                        {
                            "channel_name" : "email",
                            "receiver_identity" : "a@a.com"
                        }
                    ],
                    "created" : ISODate("2021-11-17T06:18:12.337Z"),
                    "updated" : ISODate("2021-11-17T06:18:12.337Z"),
                    "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
                    "updated_by" : null
                }
            ],
            "created" : ISODate("2021-11-18T03:30:01.307Z"),
            "updated" : ISODate("2021-11-18T03:30:01.307Z"),
            "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
            "updated_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
            "recipient_list" : [ 
                "a98888a2-e347-4d26-92df-aed8ce4916a9"
            ]
        }, 
        {
            "_id" : "ecd34cad-b56c-4248-875d-170523cfd7de",
            "notification_name" : "string",
            "rule" : {
                "additionalProp1" : "string",
                "additionalProp2" : "string",
                "additionalProp3" : "string"
            },
            "search_tags" : [ 
                "string", 
                "additionalProp1", 
                "additionalProp2", 
                "additionalProp3"
            ],
            "group_recipients" : [ 
                {
                    "_id" : "32d09a03-1ff0-422c-9de6-6df09aeeb519",
                    "group_name" : "my_sh_group",
                    "channels" : [ 
                        {
                            "channel_name" : "telegram",
                            "receiver_identity" : "novembersh"
                        }
                    ],
                    "created" : ISODate("2021-11-18T03:27:58.424Z"),
                    "updated" : ISODate("2021-11-18T03:27:58.424Z"),
                    "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
                    "updated_by" : null
                }, 
                {
                    "_id" : "7accb3f3-0fc1-4f23-b349-e7832fa99832",
                    "group_name" : "my_sh_group",
                    "channels" : [ 
                        {
                            "channel_name" : "email",
                            "receiver_identity" : "s@s.com"
                        }, 
                        {
                            "channel_name" : "slack",
                            "receiver_identity" : "ideas"
                        }, 
                        {
                            "channel_name" : "telegram",
                            "receiver_identity" : "-686779898_match"
                        }
                    ],
                    "created" : ISODate("2021-11-18T03:28:18.823Z"),
                    "updated" : ISODate("2021-11-18T03:28:18.823Z"),
                    "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
                    "updated_by" : null
                }, 
                {
                    "_id" : "d5789011-0bae-4bd5-9acf-eb5af8f04813",
                    "group_name" : "admins",
                    "channels" : [ 
                        {
                            "channel_name" : "email",
                            "receiver_identity" : "a@a.com"
                        }
                    ],
                    "created" : ISODate("2021-11-17T06:18:12.337Z"),
                    "updated" : ISODate("2021-11-17T06:18:12.337Z"),
                    "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
                    "updated_by" : null
                }
            ],
            "created" : ISODate("2021-11-17T06:18:35.580Z"),
            "updated" : ISODate("2021-11-17T06:18:35.580Z"),
            "created_by" : "456ba93c-e197-4f06-96b2-4086562e294c",
            "updated_by" : null
        }
    ],

looks like group_recipients was merged, this is incorect and not expect behaviour, how it's should correct?看起来 group_recipients 被合并了,这是不正确的并且不期望行为,它应该如何正确?

Each $lookup is executed once per document, not once per array entry.每个$lookup每个文档执行一次,而不是每个数组条目执行一次。

If you refer to a sub-field of an array of documents, like "notifications.group_recipients"如果您引用文档数组的子字段,例如“notifications.group_recipients”

This lookup stage:这个查找阶段:

{"$lookup":
    {
        "from":"alert_service_group_recipients",
        "localField":"notifications.group_recipients",
        "foreignField":"_id",
        "as":"notifications.group_recipients"
    }
},

Would be roughly equivalent to:大致相当于:

var doc = document in the pipeline;
var recipients_to_find = doc.notifications.reduce((acc,d) => acc.concat(d.group_recipients),[]);
var found=db.alert_service_group_recipients.find({_id:{$in:recipients_to_find}}).toArray();
doc.notifications.group_recipients = found;

If you want to perform a separate lookup for each notification, you will need to:如果您想对每个通知执行单独的查找,您将需要:

  • split the notifications out into separate documents, perhaps with $unwind将通知拆分为单独的文档,可能使用$unwind
  • perform each $lookup执行每个$lookup
  • $group to reassemble the array $group重新组装数组
  • $project or $replaceRoot to form the final document. $project$replaceRoot以形成最终文档。

This might look something like:这可能看起来像:

db.alert_service_alert.aggregate([
  {"$addFields": {"uuid": "$_id"}},
  {"$project": {"_id": 0}},
  {"$lookup": {
      "from": "alert_service_notification",
      "localField": "notifications",
      "foreignField": "_id",
      "as": "notifications"
  }},
  {"$unwind": "$notifications"},
  {"$lookup": {
      "from": "alert_service_group_recipients",
      "localField": "notifications.group_recipients",
      "foreignField": "_id",
      "as": "notifications.group_recipients"
  }},
  {"$group": {
      "_id": "$_uuid",
      "original": {"$first": "$$ROOT"},
      "notification": {"$push": "$notifications"}
  }},
  {"$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
            "$original",
            {"notifications": "$notification"}
        ]
      }
  }}
])

Playground操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM