[英]How to use $lookup on array of subdocuments
我有這些架構:
const chatbots = new Schema({
name: String,
campaigns: [{
name: String,
channels: [{
_id: String,
name: String,
budget: Number
}]
}]
});
const chatbotusers = new Schema({
name: String,
campaign_channel: String
})
我需要獲得一個活動列表,其中對於每個頻道,我有 ChatbotUsers 的總數。 像這樣的東西:
[
{
"name": "Campaign #1",
"channels": {
"_id": "eyRyZ1gD0",
"name": "Channel #1",
"users": 10
}
},
{
"name": "Campaign #1",
"channels": {
"_id": "tsKH7WxE",
"name": "Channel #2",
"users": 4
}
}
]
有任何想法嗎?
我得到的最遠的是這樣的:
{
$lookup: {
from: "chatbotusers",
localField: "channels._id",
foreignField: "campaign_channel",
as: "users",
}
},
{
$project: {
name: "$name",
channels: {
$map: {
input: "$channels",
as: "channel",
in: {
_id: "$$channel._id",
name: "$$channel.name",
users: { $size: "$users" },
}
}
}
}
}
但它匯總了營銷活動的用戶,而不是頻道。
(對不起,如果問題標題不合適,我什至不知道如何正確提問)
你可以試試這個查詢:
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
}
}
])
注意:可以有多種方法來做到這一點,但通過這種方式,我們正在處理來自聊天機器人集合的相同數量的文檔,而不是通過執行$unwind
來分解文檔,這在您擁有龐大的數據集時可能會有所幫助。
上面的查詢應該可以為您提供所需的信息,但無論如何,如果它很慢或者您想增強它,那么在這里:
{
user: {
$size: {
$filter: {
input: "$users", as: "e",
cond: {
$eq: [
"$$e.campaign_channel",
"$$this._id"
]
}
}
}
}
}
我們在每個廣告系列中的每個頻道遍歷users數組的地方,因此而不是每次都在查找后迭代 - 您可以使用reduce
迭代用戶一次以獲取每個唯一的Campaign_channel 的計數,將此數據替換為users數組,即您可以直接獲取用戶數的方式。 通常,上述查詢的主要目的是保留原始文檔結構,使用較少的階段。
或者,您可以使用此查詢,它不會保留原始文檔結構(輸出中的文檔數量也可能超過您收集的文檔數量),但可以執行您需要的操作:
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
}
}
])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.