猫鼬populate()无法正常工作

时间:2020-03-30 17:11:07

标签: node.js mongodb express mongoose mongoose-populate

我有一个PaymentCard和一个User模式,并且想要在创建新的PaymentCard记录以将该特定卡链接到特定客户时定义现有用户的ID。它确实使用客户的mongoID创建了PaymentCard文档,但是使用.populate()查询不会在任何用户上返回任何卡,并在所有用户上返回空数组。

2 个答案:

答案 0 :(得分:2)

要能够填充用户卡,您需要在创建付款时将卡ID推送到用户卡阵列。但我在您的addPayment中看不到这种逻辑。

此外,正如已经提到的,您需要更正您的用户架构,用户架构中卡的引用必须为"PaymentCard"。 (对于PaymentCard,您需要更正客户对"Customer"的引用)

为了使事情变得简单,我将排除jwt.verify部分,并描述我的解决方案。

正如我已经说过的,您需要将创建的卡ID保存到用户的卡阵列中:

router.post("/addPayment", async (req, res) => {
  try {
    const result = await PaymentCard.create(req.body);

    const customerId = req.body.owner;

    const response = await Customer.findByIdAndUpdate(
      customerId,
      {
        $push: { cards: result._id } //result._id has the value of newly created card
      },
      { new: true }
    );

    res.send(response);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});

假设您有这个没有任何卡的客户:

{
    "cards": [],
    "_id": "5e823f6f76322539e0fb1668",
    "name": "John",
    "surname": "Smith",
    "customerStatus": "Regular",
    "email": "john@test.com",
    "phoneNo": "123123123",
    "__v": 0
}

当我们在邮政路线中添加卡片时,该客户将是这样的:

{
    "cards": [
        "5e82400776322539e0fb1669"
    ],
    "_id": "5e823f6f76322539e0fb1668",
    "name": "John",
    "surname": "Smith",
    "customerStatus": "Regular",
    "email": "john@test.com",
    "phoneNo": "123123123",
    "__v": 0
}

添加的卡文件为:

{
    "owner": "5e823f6f76322539e0fb1668",
    "nameOnCard": "John Smith",
    "cardNumber":"1234123412341234",
    "cardIssuer": "VISA",
    "cvc": 123,
    "exp": 202008
}

现在您可以像这样填充用户卡了:

router.get("/getAll", async (req, res) => {
  try {
    const customerId = "5e823f6f76322539e0fb1668";

    const result = await Customer.findById(customerId).populate("cards");

    res.send(result);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});

这将为您提供以下结果:

{
    "cards": [
        {
            "_id": "5e82400776322539e0fb1669",
            "owner": "5e823f6f76322539e0fb1668",
            "nameOnCard": "John Smith",
            "cardNumber": "1234123412341234",
            "cardIssuer": "VISA",
            "cvc": 123,
            "exp": 202008,
            "__v": 0
        }
    ],
    "_id": "5e823f6f76322539e0fb1668",
    "name": "John",
    "surname": "Smith",
    "customerStatus": "Regular",
    "email": "john@test.com",
    "phoneNo": "123123123",
    "__v": 0
}

答案 1 :(得分:0)

  1. 引用应该是模型的,而不是基础集合的,因此在这种情况下,引用的是'PaymentCard'而不是'paymentcards'
  2. 由于您要建立无限制的1-N关系,因此可以用猫鼬virtual properties解决。

在您的Customer模式下:

const Customer = new Schema({
...
});


Customer.virtual('cards', {
  ref: 'PaymentCard',
  localField: '_id',
  foreignField: 'owner',
  justOne: false
});

module.exports = ...

然后您可以使用.populate('cards')来获取虚拟内容