猫鼬填充()不按预期工作
Mongoose populate() not working as desired
我有一个 PaymentCard 和一个用户架构,并且想在创建新的 PaymentCard 记录时定义现有用户的 ID,以 link 将特定卡发送给特定客户。它确实使用客户的 mongoID 创建了 PaymentCard 文档,但是使用 .populate() 查询不会 return 任何用户的任何卡,并且 return 所有用户的空数组。
- ref 应该指向模型而不是底层集合,所以在这种情况下指向
'PaymentCard'
而不是 'paymentcards'
。
- 因为你想要一个无限的
1-N
关系,这可以用 mongoose virtual properties. 来解决
在您的 Customer
架构上:
const Customer = new Schema({
...
});
Customer.virtual('cards', {
ref: 'PaymentCard',
localField: '_id',
foreignField: 'owner',
justOne: false
});
module.exports = ...
然后可以使用.populate('cards')
获取虚拟
的内容
为了能够从用户那里填充卡片,您需要在创建付款时将卡片 ID 推送到用户卡片数组。但我在你的 addPayment
.
中看不到这种逻辑
此外,如前所述,您需要更正用户架构,对于用户架构中的卡片,ref 必须是 "PaymentCard"
。 (对于 PaymentCard,您需要将客户的 ref 更正为 "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
}
当我们用 post 路由添加一张卡时,这个客户将是这样的:
{
"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
}
我有一个 PaymentCard 和一个用户架构,并且想在创建新的 PaymentCard 记录时定义现有用户的 ID,以 link 将特定卡发送给特定客户。它确实使用客户的 mongoID 创建了 PaymentCard 文档,但是使用 .populate() 查询不会 return 任何用户的任何卡,并且 return 所有用户的空数组。
- ref 应该指向模型而不是底层集合,所以在这种情况下指向
'PaymentCard'
而不是'paymentcards'
。 - 因为你想要一个无限的
1-N
关系,这可以用 mongoose virtual properties. 来解决
在您的 Customer
架构上:
const Customer = new Schema({
...
});
Customer.virtual('cards', {
ref: 'PaymentCard',
localField: '_id',
foreignField: 'owner',
justOne: false
});
module.exports = ...
然后可以使用.populate('cards')
获取虚拟
为了能够从用户那里填充卡片,您需要在创建付款时将卡片 ID 推送到用户卡片数组。但我在你的 addPayment
.
此外,如前所述,您需要更正用户架构,对于用户架构中的卡片,ref 必须是 "PaymentCard"
。 (对于 PaymentCard,您需要将客户的 ref 更正为 "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
}
当我们用 post 路由添加一张卡时,这个客户将是这样的:
{
"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
}