Вы можете попробовать этот запрос:
db.chatbots.aggregate([
{
$lookup: {
from: "chatbotusers",
localField: "campaigns.channels._id",
foreignField: "campaign_channel",
as: "users"
}
},
{
$addFields: {
campaigns: {
$map: {
input: "$campaigns",
as: "eachCampaign",
in: {
$mergeObjects: ['$$eachCampaign', {
channels:
{
$reduce: {
input: "$$eachCampaign.channels",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[
{
$mergeObjects: [
"$$this",
{
user: {
$size: {
$filter: {
input: "$users",
as: "e",
cond: {
$eq: [
"$$e.campaign_channel",
"$$this._id"
]
}
}
}
}
}
]
}
]
]
}
}
}
}]
}
}
}
}
},
{
$project: {
users: 0
}
}
])
Примечание: Для этого может быть несколько способов, но в этом случае мы работаем над одним и тем же документом из chatbots коллекция, а не взрываются документы, выполняя $unwind
, что может быть полезно, когда у вас огромный набор данных.
Тест: MongoDB-Playground
Этот запрос должен дать вам то, что нужно, но в любом случае, если он медленный или вы думаете, чтобы улучшить его, тогда здесь:
{
user: {
$size: {
$filter: {
input: "$users", as: "e",
cond: {
$eq: [
"$$e.campaign_channel",
"$$this._id"
]
}
}
}
}
}
Где мы повторяем через users массив для каждого канала в каждой кампании, поэтому вместо итерации каждый раз, сразу после поиска - Вы можете перебрать users за один раз, используя reduce
, чтобы получить счетчик каждого уникального campaign_channel замените эти данные массивом users , таким образом, вы можете получить количество пользователей напрямую. В общем, основной целью вышеупомянутого запроса является сохранение исходной структуры документа с меньшим количеством используемых этапов.
В качестве альтернативы вы можете использовать этот запрос, который не сохраняет исходную структуру do c (также нет документов в Вывод может быть больше, чем у вас в коллекции), но может делать то, что вам нужно:
db.chatbots.aggregate([
{
$unwind: "$campaigns"
},
{
$unwind: "$campaigns.channels"
},
{
$lookup: {
from: "chatbotusers",
localField: "campaigns.channels._id",
foreignField: "campaign_channel",
as: "users"
}
},
{
$addFields: {
"channels": "$campaigns.channels",
campaigns: "$campaigns.name"
}
},
{
$addFields: {
"channels.users": {
$size: "$users"
}
}
},
{
$project: {
users: 0
}
}
])
Тест: MongoDB-Playground