【问题标题】:mongoose filter nested array of object by value in the object猫鼬按对象中的值过滤嵌套的对象数组
【发布时间】:2020-10-28 01:35:00
【问题描述】:

我有这样的订单架构

const OrderSchema = new Schema({
  user: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
  orderDate: { type: Date, default: Date.now },
  products: { type: Array, default: [] }
});

const Order = mongoose.model("Order", OrderSchema);
module.exports = Order;

每个订单属于特定的客户(用户),用户可以从不同的卖家处购买产品

所以 products 数组是这样的:

"products" : [
      {
        _id: "5f0289147b9b980f40d4f2e6",
        product: ObjectId("5f02879f7160ae0c2c203cdf"),
        quantity: 1
      },
      {
        _id: "5f0289177b9b980f40d4f2e7",
        product: ObjectId("5f02879f7160ae0c2c203fgg"),
        quantity: 1
      }
    ]

数组中的每个产品都是这样的:

"product" : {
  _id: "5f02879f7160ae0c2c203cdf",
  name: "Some Car",
  category: "5f027c5ca1b94820b856c508",
  seller: "5f0276cf965f8c29e019a7f1" //seller can be different for each product
}

所以我想要实现的是过滤所有订单以获取每个卖家销售的所有产品。 就像如果我是卖家并且我已登录,我想将我出售的所有产品收集到订单集合中

我做了一个方法,我获取所有 Orders 集合,然后将产品填充到 products 数组中,并根据我想要的条件过滤所有数据,它对我有用,但它有 2 个 foreach,所以越大数据变得越慢,应用程序就会越慢,那么有没有一种可用的方法我可以只使用猫鼬来做到这一点?还是这是最好的方法?

Order.find()
  .populate({ path: "products.product", model: "Product" })
  .exec((err, orders) => {
    if (err) res.status(400).json({ message: "Couldn't find user", err });
    else {
      let len = orders.length;
      let orderCurInx = 0;
      let productsToDeliver = [];

      orders.forEach(order => {
        ++orderCurInx;

        order.products.forEach(item => {
          if (item.product.seller == anySellerId) {
            productsToDeliver.push(product);
          }
        });
      });

      if (len == orderCurInx) {
        return res.status(200).json({ orders });
      }
    }
  });

【问题讨论】:

  • 总结一下 - 您想获得所有订单,其中一个产品的卖家 ID 与给定的卖家 ID 匹配?
  • 您可以直接使用聚合而不是使用查找然后过滤元素,但要建议您必须共享预期输出的管道
  • @harshitkohli 是的,我认为您的方法与下面提供的一种 eol 相同,非常感谢你们

标签: node.js express mongoose


【解决方案1】:

为了获得所有订单,其中一个产品中的卖家 ID 与给定的卖家 ID 匹配,您可以使用 $lookup$match-pipelines 组合的聚合:

db.getCollection('orders').aggregate([{
            $lookup: {
                from: "products",
                localField: "products.product",
                foreignField: "_id",
                as: "mappedProducts"
            }
        }, {
            $match: {
                "mappedProducts.seller": ObjectId("5f04bae5698dc66950a991a3")
            }
        }
    ]);

其工作原理是$lookup 将在指定集合中搜索foreignField(在这种情况下为products)并将找到的product-documents 添加到新数组下的order-document-名为mappedProducts 的属性(可以任意命名)。

剩下要做的就是匹配那些seller-id 与给定id 匹配的文档。

【讨论】:

  • 谢谢你,我会试试给你一个反馈:)
  • 我真的很欣赏这种方法,但我会查找聚合,您的代码会根据我的需要返回整个订单对象(带有订单 _id 和 orderDate),但它与卖家 ID 不匹配并返回所有产品由不同的卖家在 mappedProducts
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-17
  • 2020-02-20
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
相关资源
最近更新 更多