猫鼬递归嵌套
mongoose recursive nesting
在我的项目中,用户可以创建产品。每个用户都有一个对其所有产品的引用,每个产品都有一个对其用户的引用。
用户和产品都有一个 'name' 字段。
我需要获取所有用户产品数组,在该数组中我想要产品名称和
创建它的用户名(只有那些字段,没有其他字段)。
例如:
用户:
{ _id: 1, name: 'josh', productIds: [1,3]}
{ _id: 2, name: 'sheldon', productIds: [2]}
产品:
{ _id: 1, name: 'table', price: 45, userId: 1}
{ _id: 2, name: 'television', price: 25 userId: 2}
{ _id: 3, name: 'chair', price: 14 userId: 1}
我想得到以下结果:
{ _id: 1, name: 'josh',
products: {
{ _id: 1, name: 'table', user: { _id: 1, name: 'josh' },
{ _id: 3, name: 'chair', user: { _id: 1, name: 'josh' },
}
}
{ _id: 2, name: 'sheldon',
products: {
{ _id: 2, name: 'television', userId: { _id: 2, name: 'sheldon' }
}
}
我尝试了以下查询,它没有填充内部 userId,只留下了 id(没有名字):
User.aggregate([
{
$lookup:
{
from: 'products',
localField: 'productIds',
foreignField: '_id',
as: 'products'
}
}
我还尝试了以下方法,它与第一个查询的效果相同,只是它只为每个用户重试了第一个产品:
User.aggregate([
{
$lookup:
{
from: 'products',
localField: 'productIds',
foreignField: '_id',
as: 'products'
}
},
{
$unwind: {
path: "$products",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: "user",
localField: "products.userId",
foreignField: "_id",
as: "prodUsr",
}
},
{
$group: {
_id : "$_id",
products: { $push: "$products" },
"doc": { "$first": "$$ROOT" }
}
},
{
"$replaceRoot": {
"newRoot": "$doc"
}
}
产品:
const schema = new Schema(
{
name: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
userId: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
}
);
module.exports = mongoose.model('Product', schema);
用户:
const schema = new Schema(
{
name: {
type: String,
required: true,
unique: true
},
productIds: [{
type: Schema.Types.ObjectId,
ref: 'Product',
require: false
}],
{ timestamps: true }
);
module.exports = mongoose.model('User', schema);
任何帮助将不胜感激
对于 $lookup with custom pipeline 和另一个嵌套的 $lookup
来说,这看起来是一个完美的场景。内部的允许您处理 product-> user
关系,而外部的处理 user -> product
一个:
db.Users.aggregate([
{
$project: {
productIds: 0
}
},
{
$lookup: {
from: "Products",
let: { user_id: "$_id" },
pipeline: [
{
$match: {
$expr: {
$eq: [ "$userId", "$$user_id" ]
}
}
},
{
$lookup: {
from: "Users",
localField: "userId",
foreignField: "_id",
as: "user"
}
},
{
$unwind: "$user"
},
{
$project: {
"user.productIds": 0,
"price": 0,
"userId": 0
}
}
],
as: "products"
}
}
])
在我的项目中,用户可以创建产品。每个用户都有一个对其所有产品的引用,每个产品都有一个对其用户的引用。
用户和产品都有一个 'name' 字段。
我需要获取所有用户产品数组,在该数组中我想要产品名称和 创建它的用户名(只有那些字段,没有其他字段)。
例如:
用户:
{ _id: 1, name: 'josh', productIds: [1,3]}
{ _id: 2, name: 'sheldon', productIds: [2]}
产品:
{ _id: 1, name: 'table', price: 45, userId: 1}
{ _id: 2, name: 'television', price: 25 userId: 2}
{ _id: 3, name: 'chair', price: 14 userId: 1}
我想得到以下结果:
{ _id: 1, name: 'josh',
products: {
{ _id: 1, name: 'table', user: { _id: 1, name: 'josh' },
{ _id: 3, name: 'chair', user: { _id: 1, name: 'josh' },
}
}
{ _id: 2, name: 'sheldon',
products: {
{ _id: 2, name: 'television', userId: { _id: 2, name: 'sheldon' }
}
}
我尝试了以下查询,它没有填充内部 userId,只留下了 id(没有名字):
User.aggregate([
{
$lookup:
{
from: 'products',
localField: 'productIds',
foreignField: '_id',
as: 'products'
}
}
我还尝试了以下方法,它与第一个查询的效果相同,只是它只为每个用户重试了第一个产品:
User.aggregate([
{
$lookup:
{
from: 'products',
localField: 'productIds',
foreignField: '_id',
as: 'products'
}
},
{
$unwind: {
path: "$products",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: "user",
localField: "products.userId",
foreignField: "_id",
as: "prodUsr",
}
},
{
$group: {
_id : "$_id",
products: { $push: "$products" },
"doc": { "$first": "$$ROOT" }
}
},
{
"$replaceRoot": {
"newRoot": "$doc"
}
}
产品:
const schema = new Schema(
{
name: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
userId: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
}
);
module.exports = mongoose.model('Product', schema);
用户:
const schema = new Schema(
{
name: {
type: String,
required: true,
unique: true
},
productIds: [{
type: Schema.Types.ObjectId,
ref: 'Product',
require: false
}],
{ timestamps: true }
);
module.exports = mongoose.model('User', schema);
任何帮助将不胜感激
对于 $lookup with custom pipeline 和另一个嵌套的 $lookup
来说,这看起来是一个完美的场景。内部的允许您处理 product-> user
关系,而外部的处理 user -> product
一个:
db.Users.aggregate([
{
$project: {
productIds: 0
}
},
{
$lookup: {
from: "Products",
let: { user_id: "$_id" },
pipeline: [
{
$match: {
$expr: {
$eq: [ "$userId", "$$user_id" ]
}
}
},
{
$lookup: {
from: "Users",
localField: "userId",
foreignField: "_id",
as: "user"
}
},
{
$unwind: "$user"
},
{
$project: {
"user.productIds": 0,
"price": 0,
"userId": 0
}
}
],
as: "products"
}
}
])