Mongoose聚合$查找返回空数组' as'场地
假设我们有两个集合:订单
和卖家
eBay像业务一样,客户可以从单个卖家那里订购项目。
每个订单
包含卖方
字段,该字段列出了商店所有者的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);
当我尝试使用$查找时,
const aggregateOrdersWithSellerInfo = await Order.aggregate([
{
$lookup: {
from: 'Seller',
localField: 'seller',
foreignField: '_id',
as: 'seller_info',
},
},
]).exec();
seller_info
fields(ex:gengregateOrderSwithSellerInfo [0] .seller_info
)
> (0) []
所有 订单等字段,例如:
// Seller doc
{
_id: ObjectId("62aa38d68e006f3006efe520"),
firstName: 'Nikki',
__v: 0
}
的示例
{
_id: ObjectId("62aa38d68e006f3006efe522"),
seller: ObjectId("62aa38d68e006f3006efe520"),
item: 'Mango Body Butter',
__v: 0
}
以下是doc doc
销售商
每个
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();
})();
Let's say we have two collections: Order
and Seller
for an Ebay like business where customers can order items from individual sellers.
Each Order
contains a seller
field which lists the ID of the shop owner.
const orderSchema = new mongoose.Schema({
seller: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'Seller' },
item: { type: String },
});
const Order = mongoose.model('Order', orderSchema);
When I try to use $lookup
const aggregateOrdersWithSellerInfo = await Order.aggregate([
{
$lookup: {
from: 'Seller',
localField: 'seller',
foreignField: '_id',
as: 'seller_info',
},
},
]).exec();
all seller_info
fields (ex: aggregateOrdersWithSellerInfo[0].seller_info
) return an empty array:
> (0) []
But I would expect it to return the seller associated with the seller
field on each Order
such as:
// Seller doc
{
_id: ObjectId("62aa38d68e006f3006efe520"),
firstName: 'Nikki',
__v: 0
}
Here's an example of the Order doc
{
_id: ObjectId("62aa38d68e006f3006efe522"),
seller: ObjectId("62aa38d68e006f3006efe520"),
item: 'Mango Body Butter',
__v: 0
}
How to get the associated seller document using aggregation?
Full Code
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();
})();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是该系列的名称。
seller.collection.collectionname
保留'卖家'
so 复数和 lowercase 的收集名称。您也可以从:seller.collection.collectionname 中进行
,而不是静态键入名称
the issue was the name of the collection.
Seller.collection.collectionName
holds the collection name which was'sellers'
so plural and lowercase.You can also do
from: Seller.collection.collectionName
instead of statically typing the name