简体   繁体   中英

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

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

"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,

"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?

Each $lookup is executed once per document, not once per array entry.

If you refer to a sub-field of an array of documents, like "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
  • perform each $lookup
  • $group to reassemble the array
  • $project or $replaceRoot to form the final document.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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