Mongoose聚合$查找返回空数组' as'场地

发布于 2025-02-07 13:47:34 字数 3612 浏览 1 评论 0原文

假设我们有两个集合:订单卖家 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何以心动 2025-02-14 13:47:34

问题是该系列的名称。

seller.collection.collectionname保留'卖家' so 复数 lowercase 的收集名称。

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

您也可以从: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.

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

You can also do from: Seller.collection.collectionName instead of statically typing the name

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文