我正在尝试使用 node.js MongoDB 驱动程序向查找结果中添加一个字段。用户有两种提要 1. 他或她自己的提要和 2. 共享提要。所以我需要两者兼而有之,然后将它们结合起来。这是我的原始查询,效果很好:
client.db('atlas').collection('users').aggregate([
{ $match: { user_id: userId } },
{
$lookup: {
from: 'feeds',
localField: "user_id",
foreignField: "user_id",
as: "feeds"
}
},
{
$lookup: {
from: 'shares',
localField: 'email',
foreignField: "share",
as: "shares"
}
},
{
$lookup: {
from: 'feeds',
localField: 'shares.feed_id',
foreignField: "_id",
as: "shared_feeds"
}
},
{
$addFields: { 'shared_feeds.share': true }
},
{
$project: {
user_id: 1,
first_name: 1,
last_name: 1,
email: 1,
feeds: { $concatArrays: [ '$feeds', '$shared_feeds' ] }
}
}
])
但我想在“提要”的第二次查找中添加一个字段,所以我尝试使用这样的管道:
{
$lookup: {
from: 'feeds',
let: { shareId: '$shares.feed_id' },
pipeline: [
{ $match: { '_id': ObjectId('$$shareId') } }
],
as: "shared_feeds"
}
}
但我无法匹配 ObjectId
。该变量似乎不起作用。我做错了什么?
样本集合: 用户:
[
{
"_id" : ObjectId("5e970a1f797c08e70ce4e2f6"),
"user_id" : "testuserid",
"first_name" : "Jacopo",
"last_name" : "Belbo",
"email" : "test@test.com"
}
]
提要:
[
{
"_id" : ObjectId("5f29b02318ecbf0083f01f1e"),
"name" : "test csv",
"user_id" : "auth0|5eac6faa1cc1ac0c147b5b16",
"type" : "feed",
"created_at" : ISODate("2020-08-04T18:59:47.640Z"),
"updated_at" : ISODate("2020-08-04T18:59:47.640Z")
},
{
"_id" : ObjectId("5f29b05d18ecbf0083f01f1f"),
"name" : "typtap-small",
"user_id" : "auth0|5f1b2da0e60194003d714680",
"url" : "http://localstack:4572/atlas/usertes",
"type" : "feed",
"created_at" : ISODate("2020-08-04T19:00:45.886Z"),
"updated_at" : ISODate("2020-08-04T19:00:45.886Z")
}
]
分享:
[
{
"_id" : ObjectId("5f29b07318ecbf0083f01f20"),
"feed_id" : ObjectId("5f29b05d18ecbf0083f01f1f"),
"share" : "test@test.com",
"type" : "share",
"recipient" : "email",
"created_at" : ISODate("2020-08-04T19:01:07.668Z"),
"updated_at" : ISODate("2020-08-04T19:01:07.668Z")
}
]
最佳答案
在 let: { shareId: '$shares.feed_id' }
中,您将 ObjectId
传递给 shareId
。所以你不能在 match
阶段用 ObjectId()
包装。当您在多个条件的查找中使用管道时只需使用 $expr
{
$match: {
$expr: {
$eq: [
"$$shareId",
"$_id"
]
}
}
}
更新 1.
当你在$lookup
中使用管道时,你需要使用$expr
,引用$expr in lookup .一旦你得到输出,你就会有一个数组,所以 $unwind
它并进行连接。然后将其分组以避免重复。
更新 2
mongo 脚本
[
{
$match: {
user_id: "testuserid"
}
},
{
$lookup: {
from: "feeds",
localField: "user_id",
foreignField: "user_id",
as: "feeds"
}
},
{
$lookup: {
from: "shares",
localField: "email",
foreignField: "share",
as: "shares"
}
},
{
$unwind: {
path: "$shares",
preserveNullAndEmptyArrays: false
}
},
{
$lookup: {
from: "feeds",
let: {
shareId: "$shares.feed_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$$shareId",
"$_id"
]
}
}
}
],
as: "shared_feeds"
}
},
{
$group: {
_id: "$_id",
user_id: {
$first: "$user_id"
},
first_name: {
$first: "$first_name"
},
last_name: {
$first: "$last_name"
},
email: {
$first: "$email"
},
feeds: {
$first: "$feeds"
},
shares: {
$addToSet: "$shares"
},
shared_feeds: {
$addToSet: "$shared_feeds"
}
}
},
{
$addFields: {
shared_feeds: {
$reduce: {
input: "$shared_feeds",
initialValue: [],
in: {
$setUnion: [
"$$this",
"$$value"
]
}
}
}
}
},
{
$addFields: {
"shared_feeds.share": true
}
},
{
$project: {
user_id: 1,
first_name: 1,
last_name: 1,
email: 1,
feeds: {
$concatArrays: [
"$feeds",
"$shared_feeds"
]
}
}
}
]
关于mongodb - 在 MongoDB 中为 $lookup 结果添加一个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63272936/