在架构中引用objectIds和其他参数的最佳方法是什么?

时间:2019-11-10 18:11:40

标签: node.js mongodb mongoose

我正在为订单模型创建一个架构,该架构将跟踪订购的商品以及所购买的数量。我想将itemId引用和数量作为一个数组捆绑在一起,放在一个参数中。

我创建了一个数组,其中包含对ObjectId的引用以及其他Number类型。我目前无法使用.populate()查询来填充产品信息。

订单架构

const mongoose = require("mongoose");
const { Schema } = mongoose;

const orderSchema = new Schema({
  orderNumber: String,
 _itemsOrdered: [
    {
      itemId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "menuItems"
      },
      quantity: Number
    }
  ]
});

mongoose.model("orders", orderSchema);

MenuItem架构

const mongoose = require("mongoose");
const { Schema } = mongoose;

const MenuItemSchema = new Schema({
  imageURL: String,
  name_en: String,
  name_es: String,
  type_en: String,
  type_es: String,
  description_en: String,
  description_es: String,
  dietaryCallouts: [String],
  price: Number
});

mongoose.model("menuItems", MenuItemSchema);

module.export = MenuItemSchema;

我能够保存记录,但是不能使用以下查询填充MenuItem信息:

订单控制器

  async show(req, res, next) {
    try {
      const orderId = req.params.id;

      let order = await Order.findById({ _id: orderId }).populate(
        "_itemsOrdered.itemId"
      );

      res.send(order);
    } catch (err) {
      res.status(402).send(err);
    }
  }

这里是保存到数据库的订单对象。

订单对象

{
    "_id": "5dc93b9c0085b8045e0c8aa3",
    "orderNumber": "Order 3",
    "_itemsOrdered": [
        {
            "_id": "5dc93b9c0085b8045e0c8aa5",
            "itemId": "5dc7f814a2679b47319a79a4",
            "quantity": 1
        },
        {
            "_id": "5dc93b9c0085b8045e0c8aa4",
            "itemId": "5dc7e5c7de590744c46f93da",
            "quantity": 2
        }
    ],
    "__v": 0
}

1 个答案:

答案 0 :(得分:1)

您的订单架构必须是这样的:

const orderSchema = new Schema({
  orderNumber: String,
  _itemsOrdered: [
    {
      itemId: { type: mongoose.Schema.Types.ObjectId, ref: "menuItems" },
      quantity: Number
    }
  ]
});

您可以使用以下路线创建订单文档。

router.post("/order", async (req, res, next) => {

  try {
    const { orderNumber, _itemsOrdered } = req.body;

    let order = new Order({ orderNumber, _itemsOrdered });
    order = await order.save();

    res.status(201).send(order);

  } catch (err) {
    console.log(err);
    res.status(500).send(err);
  }
});

示例正文:(您需要根据自己的ID进行更改)

{
    "orderNumber": "Order 1",
    "_itemsOrdered": [
        {"itemId": "5dc90346222b892434e4675a", "quantity" : 1 }, 
        {"itemId": "5dc90359222b892434e4675b", "quantity" : 2 }
    ]
}

要获取订单及其商品,可以使用如下填充:

router.get("/orders/:id", async (req, res) => {
  try {
    const orderAndItems = await Order.findById(req.params.id).populate(
      "_itemsOrdered.itemId"
    );

    res.send(orderAndItems);
  } catch (err) {
    console.log(err);
    res.status(500).send(err);
  }
});

这将为您提供如下结果:

{
    "_id": "5dc904db8407a217b4dfe6f4",
    "orderNumber": "Order 1",
    "_itemsOrdered": [
        {
            "_id": "5dc904db8407a217b4dfe6f6",
            "itemId": {
                "_id": "5dc90346222b892434e4675a",
                "name_en": "item 1",
                "price": 1,
                "__v": 0
            },
            "quantity": 1
        },
        {
            "_id": "5dc904db8407a217b4dfe6f5",
            "itemId": {
                "_id": "5dc90359222b892434e4675b",
                "name_en": "item 2",
                "price": 2,
                "__v": 0
            },
            "quantity": 2
        }
    ],
    "__v": 0
}