[英]Mongoose aggregation $lookup returns empty array in 'as' field
假設我們有兩個集合: Order
和Seller
,用於類似 Ebay 的業務,客戶可以從單個賣家處訂購商品。
每個Order
都包含一個seller
字段,其中列出了店主的 ID。
const orderSchema = new mongoose.Schema({
seller: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'Seller' },
item: { type: String },
});
const Order = mongoose.model('Order', orderSchema);
當我嘗試使用 $lookup
const aggregateOrdersWithSellerInfo = await Order.aggregate([
{
$lookup: {
from: 'Seller',
localField: 'seller',
foreignField: '_id',
as: 'seller_info',
},
},
]).exec();
所有seller_info
字段(例如: aggregateOrdersWithSellerInfo[0].seller_info
)返回一個空數組:
> (0) []
但我希望它會返回與每個Order
上的seller
字段相關的賣家,例如:
// Seller doc
{
_id: ObjectId("62aa38d68e006f3006efe520"),
firstName: 'Nikki',
__v: 0
}
這是訂單文檔的示例
{
_id: ObjectId("62aa38d68e006f3006efe522"),
seller: ObjectId("62aa38d68e006f3006efe520"),
item: 'Mango Body Butter',
__v: 0
}
如何使用聚合獲取關聯的賣家文件?
const mongoose = require('mongoose');
const connect = async (dsn) =>
mongoose.connect(dsn, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// Order Schema
const orderSchema = new mongoose.Schema({
seller: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'Seller' },
item: { type: String },
});
const Order = mongoose.model('Order', orderSchema);
// Seller Schema
const sellerSchema = new mongoose.Schema({
firstName: { type: String },
});
const Seller = mongoose.model('Seller', sellerSchema);
// Seeder
const seedLocalDatabase = async () => {
await connect('mongodb://127.0.0.1:27017/fakewishtender');
await Seller.deleteMany({});
const sellers = [
{
firstName: 'Nikki',
},
{
firstName: 'Alice',
},
];
const sellersInsertedRes = await Seller.insertMany(sellers);
await Order.deleteMany({});
const orders = [
{
seller: sellersInsertedRes.find((seller) => seller.firstName === 'Nikki')._id,
item: 'Mango Body Butter',
},
{
seller: sellersInsertedRes.find((seller) => seller.firstName === 'Alice')._id,
item: 'Vintage Jacket',
},
];
await Order.insertMany(orders);
};
// Aggregation
(async () => {
await seedLocalDatabase();
const aggregateOrdersWithSellerInfo = await Order.aggregate([
{
$lookup: {
from: 'Seller',
localField: 'seller',
foreignField: '_id',
as: 'seller_info',
},
},
]).exec();
const allSellers = await Seller.find({});
const allOrders = await Order.find({});
const sellersWithOrders = allOrders.map((order) =>
allSellers.filter((seller) => seller._id.toJSON() === order.seller.toJSON())
);
const sellersPopulatedWithAggregate = aggregateOrdersWithSellerInfo.map(
(order) => order.seller_info
);
console.log(
`
Sellers populated with aggregation are:
${JSON.stringify(sellersPopulatedWithAggregate)}
`
);
console.log(
`But I would expect sellers populated with aggregation to be:
${JSON.stringify(sellersWithOrders)}
`
);
mongoose.disconnect();
})();
問題是集合的名稱。
Seller.collection.collectionName
包含集合名稱,它是'sellers'
所以復數和小寫。
const aggregateOrdersWithSellerInfo = await Order.aggregate([
{
$lookup: {
from: 'sellers',
localField: 'seller',
foreignField: '_id',
as: 'seller_info',
},
},
]).exec();
您也可以from: Seller.collection.collectionName
而不是靜態輸入名稱
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.