查询以查找不包含特定 _id 项的所有文档

Query to find all documents that don't include an item of specific `_id`

// Product
const ProductSchema = new Schema<TProductModel>(
    {
        name: String,
    }
    { timestamps: true }
);
// OrderDetails
const OrderDetailsSchema = new Schema<TOrderDetailsModel>({
    product: { type: Schema.Types.ObjectId, ref: 'Product' },
    productsInOrder: { type: Number, default: 1 },
    orderLimit: Number,
    orderId: { type: Schema.Types.ObjectId, ref: 'Order' },
});
// Order
const OrderSchema = new Schema<TOrderModel>(
    {
        vendor: { type: Schema.Types.ObjectId, ref: 'Vendor' },
        products: [{ type: Schema.Types.ObjectId, ref: 'OrderDetail' 
    }],
    },
    { timestamps: true }
);

我需要找到所有 Order 文档 vendor of vendorId 并且其 products 不包含具有特定 OrderDetails =20=]

假设我有一个 Order:

const myOrder = {
    "_id": "62975f946a2047c4e9c67ac6",
    "status": "NEW",
    "vendor": {
        // vendor details
    },
    "products": [
        {
            "_id": "629763b74ede0232a7e8e2ab",
            "product": "62975f476a2047c4e9c67ab1", // this is reference to "Tape" product
            "productsInOrder": 5,
            "orderLimit": 5,
            "orderId": "62975f946a2047c4e9c67ac6",
            "__v": 0
        },
    ],
    "createdAt": "2022-06-01T12:46:12.735Z",
    "updatedAt": "2022-06-01T13:04:03.025Z",
    "orderNumber": 18,
    "__v": 3
}

添加相同的新订单时vendor

const newOrder = {
    "_id": "629763c24ede0232a7e8e2bc",
    "product": "62975f476a2047c4e9c67ab1", // this is reference to "Ladder" product 
    "productsInOrder": 1,
    "orderLimit": 5,
    "orderId": "62975f946a2047c4e9c67ac6",
    "__v": 0
}

我想找到 Order 还没有 OrderDetailsproduct 设置为 "62975f476a2047c4e9c67ab1"

我试过了

const order = await OrderModel.findOne({
    vendor,
    $ne: ['products.product', product],
});

但它 returns 一个已经有产品 product 的订单,它看起来像这样:

{
  _id: new ObjectId("62975f946a2047c4e9c67ac6"),
  status: 'NEW',
  vendor: new ObjectId("629581466e2469498cff053f"),
  products: [
    new ObjectId("62975f946a2047c4e9c67ac7"), // these 4 OrderDetails references all have the same `product`, so it shouldn't be found
    new ObjectId("629763994ede0232a7e8e298"), 
    new ObjectId("629763b74ede0232a7e8e2ab"),
    new ObjectId("629763c24ede0232a7e8e2bc")
  ],
  createdAt: 2022-06-01T12:46:12.735Z,
  updatedAt: 2022-06-01T13:04:03.025Z,
  orderNumber: 18,
  __v: 3
}

我也尝试了不同的聚合,但没有任何效果。

我需要一个查询来找到一个 Order,它不包含 OrderDetailsproduct 字段等于我提供的 productId

我想我需要在 Orderproducts 字段中填充实际的 OrderDetails 对象,然后再查看它的 product 但我不知道如何实施那个。

您可以尝试使用 MongoDB 聚合操作。 您需要查看 ID 在您的架构中是否存储为字符串或 ObjectId。

products.aggregate([
 {
  { $lookup: {
   from: "product",
   let: { "id": "$_id.product" },
   pipeline: [
     { $match: { "$expr": { "$ne": ["<your ID>", "$$id"] }}},
    ],
   as: "output"
  }}
]);

试用一下,尽量根据自己的需要做更多的调整。这只是一个 sudo 代码 有用的参考资料 https://www.mongodb.com/docs/manual/reference/operator/aggregation/ne/ https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter/

尝试添加一些架构和文档以更好地了解用户。希望这会有所帮助。

如果您已经有一个包含以下数据的 order 集合:

{
    "_id": "62975f946a2047c4e9c67ac6",
    "status": "NEW",
    "vendor": {id: 12},
    "products": [
        {
            "_id": "629763b74ede0232a7e8e2ab",
            "product": "62975f476a2047c4e9c67ab1", // this is reference to "Tape" product
            "productsInOrder": 5,
            "orderLimit": 5,
            "orderId": "62975f946a2047c4e9c67ac6",
            "__v": 0
        },
    ],
    "createdAt": "2022-06-01T12:46:12.735Z",
    "updatedAt": "2022-06-01T13:04:03.025Z",
    "orderNumber": 18,
}

例如,您想要查找带有 vendor.id: 12 的文档,而其产品不包含带有 "product": "62975f476a2047c4e9c67ab1" 的项目,您可以使用 $elemMatch:

db.orders.find({
  "vendor.id": 12,
  products: {$not: {$elemMatch: {product: "62975f476a2047c4e9c67ab1"}}}
})

Playground example

如果你想在聚合管道中间进行,你可以使用 $filter:

db.orders.aggregate([
  {$match: {"vendor.id": 12}},
  {
    $addFields: {
      removeProducts: {
        $size: {
          $filter: {
            input: "$products",
            as: "item",
            cond: {$eq: ["$$item.product", "62975f476a2047c4e9c67ab1"]}
          }
        }
      }
    }
  },
  {$match: {removeProducts: 0}},
  {$unset: "removeProducts"}
])

Aggregation playground example