在 MongoDB 聚合查找中使用以 $ 开头的字段
Use fields that start with $ in MongoDB aggregation lookup
我有一个 MongoDB 数据库,该数据库由 Spring 应用程序使用 Spring 数据填充。我想执行手动查询以连接两个集合并从此数据中提取一些统计信息。
第一个集合名为 emailCampaign
并包含此信息(简体):
{
"_id" : ObjectId("5db85687307b0a0d184448db"),
"name" : "Welcome email",
"subject" : "¡Welcome {{ user.name }}!",
"status" : "Sent",
"_class" : "com.mycompany.EmailCampaign"
}
第二个集合名为 campaignDelivery
,包含以下信息(简体):
/* 1 */
{
"_id" : ObjectId("5db183fb307b0aef3113361f"),
"campaign" : {
"$ref" : "emailCampaign",
"$id" : ObjectId("5db85687307b0a0d184448db")
},
"deliveries" : 3,
"_class" : "com.mycompany.CampaignDelivery"
}
/* 2 */
{
"_id" : ObjectId("5db85f2c307b0a0d184448e1"),
"campaign" : {
"$ref" : "emailCampaign",
"$id" : ObjectId("5db85687307b0a0d184448db")
},
"deliveries" : 5,
"_class" : "com.mycompany.CampaignDelivery"
}
最终我想获得两个 deliveries
字段的总和,但现在我仍然坚持使用基本的 JOIN:
db.emailCampaign.aggregate([
{
$lookup: {
from: 'campaignDelivery',
localField: '_id',
foreignField: 'campaign.$id',
as: 'deliveries'
}
}
])
抛出以下错误:
FieldPath field names may not start with '$'.
转义美元没有任何影响,我不能以美元开头的任何字段示例。
您可以通过在子查询中使用 uncorrelated $lookup with $objectToArray 来访问 campaign.$id
:
来解决它
db.emailCampaign.aggregate([
{ $lookup: {
from: "campaignDelivery",
let: { id: "$_id" },
pipeline: [
{ $addFields: {
refId: { $arrayElemAt: [
{ $filter: {
input: { $objectToArray: "$campaign" },
cond: { $eq: [ "$$this.k", { $literal: "$id" } ] }
} }
, 0
] }
} },
{ $match: {
$expr: { $eq: [
"$refId.v",
"$$id"
] }
} },
{ $project: {
refId: 0
} }
],
as: "deliveries"
} }
])
我有一个 MongoDB 数据库,该数据库由 Spring 应用程序使用 Spring 数据填充。我想执行手动查询以连接两个集合并从此数据中提取一些统计信息。
第一个集合名为 emailCampaign
并包含此信息(简体):
{
"_id" : ObjectId("5db85687307b0a0d184448db"),
"name" : "Welcome email",
"subject" : "¡Welcome {{ user.name }}!",
"status" : "Sent",
"_class" : "com.mycompany.EmailCampaign"
}
第二个集合名为 campaignDelivery
,包含以下信息(简体):
/* 1 */
{
"_id" : ObjectId("5db183fb307b0aef3113361f"),
"campaign" : {
"$ref" : "emailCampaign",
"$id" : ObjectId("5db85687307b0a0d184448db")
},
"deliveries" : 3,
"_class" : "com.mycompany.CampaignDelivery"
}
/* 2 */
{
"_id" : ObjectId("5db85f2c307b0a0d184448e1"),
"campaign" : {
"$ref" : "emailCampaign",
"$id" : ObjectId("5db85687307b0a0d184448db")
},
"deliveries" : 5,
"_class" : "com.mycompany.CampaignDelivery"
}
最终我想获得两个 deliveries
字段的总和,但现在我仍然坚持使用基本的 JOIN:
db.emailCampaign.aggregate([
{
$lookup: {
from: 'campaignDelivery',
localField: '_id',
foreignField: 'campaign.$id',
as: 'deliveries'
}
}
])
抛出以下错误:
FieldPath field names may not start with '$'.
转义美元没有任何影响,我不能以美元开头的任何字段示例。
您可以通过在子查询中使用 uncorrelated $lookup with $objectToArray 来访问 campaign.$id
:
db.emailCampaign.aggregate([
{ $lookup: {
from: "campaignDelivery",
let: { id: "$_id" },
pipeline: [
{ $addFields: {
refId: { $arrayElemAt: [
{ $filter: {
input: { $objectToArray: "$campaign" },
cond: { $eq: [ "$$this.k", { $literal: "$id" } ] }
} }
, 0
] }
} },
{ $match: {
$expr: { $eq: [
"$refId.v",
"$$id"
] }
} },
{ $project: {
refId: 0
} }
],
as: "deliveries"
} }
])