Решение оказалось длиннее, чем я ожидал (я надеюсь, что кто-то найдет более краткое решение), но вы идете:
db.test.aggregate([
{$unwind:"$tags"}, //unwind tags so that we can separately deal with http and https
{
$facet: {
"https": [{ // the first stage will...
$match: { // only contain documents...
"tags.Domain": /^https.*/ // that are allowed by the match the regex /^https.*/
}
}, {
$addFields: { // for all matching documents...
"tags.Domain": {"$substr": ["$tags.Domain",8,-1]} // we change the tags.Domain field to required substring (skip 8 characters and go on till the last character)
}
}],
"http": [{ // similar as above except we're doing the inverse filter using $not
$match: {
"tags.Domain": { $not: /^https.*/ }
}
}, {
$addFields: { // for all matching documents...
"tags.Domain": {"$substr": ["$tags.Domain",7,-1]} // we change the tags.Domain field to required substring (skip 7 characters and go on till the last character)
}
}
]
}
},
{ $project: { all: { $concatArrays: [ "$https", "$http" ] } } }, //we have two arrays at this point, so we just concatenate them both to have one array called "all"
//unwind and group the array by _id to get the document back in the original format
{$unwind: "$all"},
{$group: {
_id: "$all._id",
tags: {$push: "$all.tags"}
}}
])
Для удаления / с конца выможет иметь другой фасет с регулярным выражением, совпадающим с URL (что-то вроде /.*\/$/
должно работать), и использовать этот фасет также в concat.
С помощью: https://stackoverflow.com/a/49660098/5530229 и https://stackoverflow.com/a/44729563/5530229
Как сказал dnickless в первом ответе, упомянутом выше, , как всегда в структуре агрегации, это может помочьудалите отдельные этапы из конца конвейера и выполните частичный запрос, чтобы понять, что делает каждый отдельный этап.