MongoDB 使用 $lookup 的聚合仅包括(或投影)查询中 return 的一些字段
MongoDB aggregation with $lookup only include (or project) some fields to return from query
在 mongo 中,在使用 $lookup
执行 aggregation
之后,我希望 return 仅请求某些字段而不是整个文档。
我有以下查询:
db.somecollection.aggregate([{
$lookup: {
from: "campaigns",
localField: "campId",
foreignField: "_id",
as: "campaign"
}
}, {
$unwind: "$campaign"
}, {
$lookup: {
from: "entities",
localField: "campaign.clientid",
foreignField: "_id",
as: "campaign.client"
}
}]);
这个请求将 return 我这个 :
{
"_id" : ObjectId("56cc7cd1cc2cf62803ebfdc7"),
"campId" : ObjectId("56c740e4479f46e402efda84"),
"articleId" : ObjectId("56c742c06094640103ba3843"),
"campaign" : {
"_id" : ObjectId("56c740e4479f46e402efda84"),
"clientid" : ObjectId("56c740b8479f46e402efda83"),
"client" : [
{
"_id" : ObjectId("56c740b8479f46e402efda83"),
"username" : "someusername",
"shhh" : "somehashedpassword",
"email" : "mail@mail.com",
}
]
}
请求运行良好,但我想过滤 campaign.client
中的字段以仅获取例如 _id
和 username
。有没有办法在 MongoDB aggregate
请求中做到这一点?
为了帮助其他人,@SiddhartAjmera 给出了正确的答案,我只需要为 "campaign.clientid".
这样的嵌套值添加双引号
最终代码应该是:
db.somecollection.aggregate([
{
"$lookup": {
"from": "campaigns",
"localField": "campId",
"foreignField": "_id",
"as": "campaign"
}
},
{
"$unwind": "$campaign"
},
{
"$lookup": {
"from": "entities",
"localField": "campaign.clientid",
"foreignField": "_id",
"as": "campaign.client"
}
},
{
"$project": {
"_id": 1,
"campId": 1,
"articleId": 1,
"campaign._id": 1,
"campaign.clientid": 1,
"campaign.client._id": 1,
"campaign.client.username": 1
}
}
]);
只是对之前的答案补充一点:您可以将 0 放入您想要忽略的项目项中,其余的将被检索,因此您不需要将所有列表都写成 1 :
db.somecollection.aggregate([
{
"$lookup": {
"from": "campaigns",
"localField": "campId",
"foreignField": "_id",
"as": "campaign"
}
},
{
"$unwind": "$campaign"
},
{
"$lookup": {
"from": "entities",
"localField": "campaign.clientid",
"foreignField": "_id",
"as": "campaign.client"
}
},
{
"$project": {
"campaign.client.shhh": 0
}
}
])
在 $lookup
中使用 pipeline
和 $project
db.somecollection.aggregate([{
$lookup: {
from: "campaigns",
localField: "campId",
foreignField: "_id",
as: "campaign"
}
}, {
$unwind: "$campaign"
}, {
$lookup: {
from: "entities",
let: { client_id: "$campaign.clientid" },
pipeline : [
{ $match: { $expr: { $eq: [ "$_id", "$$client_id" ] } }, },
{ $project : { _id:1, username:1 } }
],
as: "campaign.client"
}
}]);
我知道现在回答这个问题已经很晚了。但在我看来,更新有时会非常有益。
项目阶段很棒,但您仍然会在 $lookup
阶段请求整个码头。这些字段仅在其后的投影阶段被过滤。
MongoDB 3.6 发布后,您现在可以将管道添加到 $lookup
阶段,以指定多个连接条件。在他们的官方文档中找到更多详细信息。
Specify Multiple Join Conditions with $lookup
您可以按如下方式转换聚合管道,以获得所需的结果:
db.somecollection.aggregate([{
$lookup: {
from: "campaigns",
localField: "campId",
foreignField: "_id",
as: "campaign"
}
}, {
$unwind: "$campaign"
}, {
$lookup: {
from: "entities",
let: {clientid: '$campaign.clientid'},
pipeline: [
{ '$match':
{ '$expr':
{
'$eq': ['$_id', '$$clientid']
}
}
},
{ '$project':
'_id': 1,
'username': 1
}
]
as: "campaign.client"
}
}]);
这样您就可以在 $lookup
阶段过滤加入集合的字段。
注意内部管道 $match
阶段内的 $$
符号。它用于表示在 let
块内定义的自定义字段。
在 mongo 中,在使用 $lookup
执行 aggregation
之后,我希望 return 仅请求某些字段而不是整个文档。
我有以下查询:
db.somecollection.aggregate([{
$lookup: {
from: "campaigns",
localField: "campId",
foreignField: "_id",
as: "campaign"
}
}, {
$unwind: "$campaign"
}, {
$lookup: {
from: "entities",
localField: "campaign.clientid",
foreignField: "_id",
as: "campaign.client"
}
}]);
这个请求将 return 我这个 :
{
"_id" : ObjectId("56cc7cd1cc2cf62803ebfdc7"),
"campId" : ObjectId("56c740e4479f46e402efda84"),
"articleId" : ObjectId("56c742c06094640103ba3843"),
"campaign" : {
"_id" : ObjectId("56c740e4479f46e402efda84"),
"clientid" : ObjectId("56c740b8479f46e402efda83"),
"client" : [
{
"_id" : ObjectId("56c740b8479f46e402efda83"),
"username" : "someusername",
"shhh" : "somehashedpassword",
"email" : "mail@mail.com",
}
]
}
请求运行良好,但我想过滤 campaign.client
中的字段以仅获取例如 _id
和 username
。有没有办法在 MongoDB aggregate
请求中做到这一点?
为了帮助其他人,@SiddhartAjmera 给出了正确的答案,我只需要为 "campaign.clientid".
这样的嵌套值添加双引号最终代码应该是:
db.somecollection.aggregate([
{
"$lookup": {
"from": "campaigns",
"localField": "campId",
"foreignField": "_id",
"as": "campaign"
}
},
{
"$unwind": "$campaign"
},
{
"$lookup": {
"from": "entities",
"localField": "campaign.clientid",
"foreignField": "_id",
"as": "campaign.client"
}
},
{
"$project": {
"_id": 1,
"campId": 1,
"articleId": 1,
"campaign._id": 1,
"campaign.clientid": 1,
"campaign.client._id": 1,
"campaign.client.username": 1
}
}
]);
只是对之前的答案补充一点:您可以将 0 放入您想要忽略的项目项中,其余的将被检索,因此您不需要将所有列表都写成 1 :
db.somecollection.aggregate([
{
"$lookup": {
"from": "campaigns",
"localField": "campId",
"foreignField": "_id",
"as": "campaign"
}
},
{
"$unwind": "$campaign"
},
{
"$lookup": {
"from": "entities",
"localField": "campaign.clientid",
"foreignField": "_id",
"as": "campaign.client"
}
},
{
"$project": {
"campaign.client.shhh": 0
}
}
])
在 $lookup
pipeline
和 $project
db.somecollection.aggregate([{
$lookup: {
from: "campaigns",
localField: "campId",
foreignField: "_id",
as: "campaign"
}
}, {
$unwind: "$campaign"
}, {
$lookup: {
from: "entities",
let: { client_id: "$campaign.clientid" },
pipeline : [
{ $match: { $expr: { $eq: [ "$_id", "$$client_id" ] } }, },
{ $project : { _id:1, username:1 } }
],
as: "campaign.client"
}
}]);
我知道现在回答这个问题已经很晚了。但在我看来,更新有时会非常有益。
项目阶段很棒,但您仍然会在 $lookup
阶段请求整个码头。这些字段仅在其后的投影阶段被过滤。
MongoDB 3.6 发布后,您现在可以将管道添加到 $lookup
阶段,以指定多个连接条件。在他们的官方文档中找到更多详细信息。
Specify Multiple Join Conditions with $lookup
您可以按如下方式转换聚合管道,以获得所需的结果:
db.somecollection.aggregate([{
$lookup: {
from: "campaigns",
localField: "campId",
foreignField: "_id",
as: "campaign"
}
}, {
$unwind: "$campaign"
}, {
$lookup: {
from: "entities",
let: {clientid: '$campaign.clientid'},
pipeline: [
{ '$match':
{ '$expr':
{
'$eq': ['$_id', '$$clientid']
}
}
},
{ '$project':
'_id': 1,
'username': 1
}
]
as: "campaign.client"
}
}]);
这样您就可以在 $lookup
阶段过滤加入集合的字段。
注意内部管道 $match
阶段内的 $$
符号。它用于表示在 let
块内定义的自定义字段。