假设我们有两个系列:OrderSeller,用于类似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);

当我try 使用$查找时

  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
  }

How to get the associated seller document using aggregation?

完整代码

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' so plurallowercase.

  const aggregateOrdersWithSellerInfo = await Order.aggregate([
    {
      $lookup: {
        from: 'sellers',
        localField: 'seller',
        foreignField: '_id',
        as: 'seller_info',
      },
    },
  ]).exec();

您也可以执行from: Seller.collection.collectionName而不是静态键入名称

Javascript相关问答推荐

如何将剧作家请求对象转换为字符串,因为它只提供promise ?

JavaScript代理不适用于打开的窗口对象

HTML/JavaScript函数未执行

为什么我的第二个OnClick Isloading值在TEK查询Mutations 查询中不起作用?

如何让\w token 在此RegEx中表现得不贪婪?

在JavaScript中对大型级联数组进行切片的最有效方法?

react 路由加载程序行为

如何避免移动设备中出现虚假调整大小事件?

Google图表时间轴—更改hAxis文本 colored颜色

如何解决useState错误—setSelect Image不是函数''

JQuery Click事件不适用于动态创建的按钮

JavaScript是否有多个`unfined`?

如何将zoom 变换应用到我的d3力有向图?

如何在JAVASCRIPT中临时删除eventListener?

Reaction-SWR-无更新组件

使用Document.Evaluate() Select 一个包含撇号的HTML元素

在验证和提交表单后使用useNavigate()进行react 重定向,使用带有加载器和操作的路由

React:防止useContext重新渲染整个应用程序或在组件之间共享数据而不重新渲染所有组件

使用API调用的VUE 3键盘输入同步问题

AG-GRIDreact 显示布尔值而不是复选框