Node.js Mongoose populate()未按预期工作
我有一张PaymentCard和一个用户模式,并希望在创建新的PaymentCard记录以将特定卡链接到特定客户时定义现有用户的ID。它确实使用客户的mongoID创建PaymentCard文档,但是使用.populate()查询不会在任何用户上返回任何卡片,并且在所有用户上返回空数组Node.js Mongoose populate()未按预期工作,node.js,mongodb,express,mongoose,mongoose-populate,Node.js,Mongodb,Express,Mongoose,Mongoose Populate,我有一张PaymentCard和一个用户模式,并希望在创建新的PaymentCard记录以将特定卡链接到特定客户时定义现有用户的ID。它确实使用客户的mongoID创建PaymentCard文档,但是使用.populate()查询不会在任何用户上返回任何卡片,并且在所有用户上返回空数组 参考应该是模型,而不是基础集合,因此在本例中,参考是'PaymentCard',而不是'paymentcards' 因为你要寻找一个无界的1-N关系,这可以用猫鼬来解决 在您的客户模式上: const Custo
'PaymentCard'
,而不是'paymentcards'
1-N
关系,这可以用猫鼬来解决客户
模式上:
const Customer = new Schema({
...
});
Customer.virtual('cards', {
ref: 'PaymentCard',
localField: '_id',
foreignField: 'owner',
justOne: false
});
module.exports = ...
然后您可以使用.populate('cards')
来获取虚拟文档的内容
'PaymentCard'
,而不是'paymentcards'
1-N
关系,这可以用猫鼬来解决客户
模式上:
const Customer = new Schema({
...
});
Customer.virtual('cards', {
ref: 'PaymentCard',
localField: '_id',
foreignField: 'owner',
justOne: false
});
module.exports = ...
然后,您可以使用
.populate('cards')
来获取虚拟卡的内容要能够从用户那里填充卡,您需要在创建付款时将卡id推送到用户卡数组。但是我在你的addPayment
中看不到这种逻辑
此外,如前所述,您需要更正您的用户架构,对于用户架构中的卡,ref必须是“PaymentCard”
。(对于PaymentCard,您需要将customer的ref改为“customer”
)
为了方便起见,我将排除jwt.verify部分,并描述我的解决方案
如前所述,您需要将创建的卡id保存到用户的卡阵列:
router.post(“/addPayment”),异步(req,res)=>{
试一试{
const result=wait PaymentCard.create(请求主体);
const customerId=req.body.owner;
const response=wait Customer.findByIdAndUpdate(
客户ID,
{
$push:{cards:result.\u id}//result.\u id具有新创建的卡的值
},
{新:正确}
);
res.send(响应);
}捕捉(错误){
控制台日志(err);
res.status(500)。发送(“出错”);
}
});
假设您的客户没有任何卡:
{
"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
}
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");
}
});
添加的卡片文档为:
{
"owner": "5e823f6f76322539e0fb1668",
"nameOnCard": "John Smith",
"cardNumber":"1234123412341234",
"cardIssuer": "VISA",
"cvc": 123,
"exp": 202008
}
现在,您可以这样填充用户卡:
{
"cards": [
"5e82400776322539e0fb1669"
],
"_id": "5e823f6f76322539e0fb1668",
"name": "John",
"surname": "Smith",
"customerStatus": "Regular",
"email": "john@test.com",
"phoneNo": "123123123",
"__v": 0
}
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
}
为了能够从用户填充卡,您需要在创建付款时将卡id推送到用户卡阵列。但是我在你的
addPayment
中看不到这种逻辑
此外,如前所述,您需要更正您的用户架构,对于用户架构中的卡,ref必须是“PaymentCard”
。(对于PaymentCard,您需要将customer的ref改为“customer”
)
为了方便起见,我将排除jwt.verify部分,并描述我的解决方案
如前所述,您需要将创建的卡id保存到用户的卡阵列:
router.post(“/addPayment”),异步(req,res)=>{
试一试{
const result=wait PaymentCard.create(请求主体);
const customerId=req.body.owner;
const response=wait Customer.findByIdAndUpdate(
客户ID,
{
$push:{cards:result.\u id}//result.\u id具有新创建的卡的值
},
{新:正确}
);
res.send(响应);
}捕捉(错误){
控制台日志(err);
res.status(500)。发送(“出错”);
}
});
假设您的客户没有任何卡:
{
"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
}
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");
}
});
添加的卡片文档为:
{
"owner": "5e823f6f76322539e0fb1668",
"nameOnCard": "John Smith",
"cardNumber":"1234123412341234",
"cardIssuer": "VISA",
"cvc": 123,
"exp": 202008
}
现在,您可以这样填充用户卡:
{
"cards": [
"5e82400776322539e0fb1669"
],
"_id": "5e823f6f76322539e0fb1668",
"name": "John",
"surname": "Smith",
"customerStatus": "Regular",
"email": "john@test.com",
"phoneNo": "123123123",
"__v": 0
}
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
}
我已经尝试引用该模型,但是它仍然不会在每个用户的cards数组中返回任何内容。您确定客户的cards属性包含任何内容吗?或者只是支付卡上的所有者财产?如果是这种情况,我怀疑您正在为cards数组寻找一个而不是一个ref。是的,每当我发出POST请求以注册一张新卡并提供现有用户的mongoID时,它都会作为ObjectID保存在新PaymentCard的owner字段中。但是,在获取客户列表的GET调用中,每个客户上的cards数组保持为空,即使使用populate()命令功能我认为问题在于,您没有更新所有者的
卡
,也没有包括新的支付卡
的id。填充者正在查看卡
数组,以确定连接到哪个id的支付卡
。如果数组为空,则不会填充任何内容。我更新了我的答案,加入了virtual
definition.Hey。使用您建议的虚拟路径会引发错误:虚拟路径“cards”与架构中的真实路径冲突,但是当我从架构中删除“cards”字段时,它不会执行任何操作,并且当获取所有用户的列表时,不会填充/包括resI中的数组。我已尝试引用该模型,但是,对于每个用户,它仍然不会在cards数组中返回任何内容您确定customer上的cards属性包含任何内容吗?或者只是支付卡上的所有者财产?如果是这种情况,我怀疑您正在为cards数组寻找一个而不是一个ref。是的,每当我发出POST请求以注册一张新卡并提供现有用户的mongoID时,它都会作为ObjectID保存在新PaymentCard的owner字段中。但是,在获取客户列表的GET调用中,每个客户上的cards数组保持为空,即使使用populate()函数,我认为问题在于您没有更新卡