我正在nodejs / express / mongodb / mongoose中构建REST API。我最近开始使用MongoDB / Mongoose,我仍有一些疑问。
我想要实现的是访问特定的用户包(用户可以拥有多个包),而且我希望能够添加到那个包包参与者/付款人。 (用户包可以有多个参与者/付款人)
我的mongoose用户模式包含其余模式。我为每个人创建了一个模式,因为我相信由于ObjectId会更容易直接找到给定的包或参与者(不确定这是否正确)。
Mongoose Modal / Schemas:
const PayerSchema = new Schema({
name: {
type: String
},
amount: {
type: Number
}
});
const BagSchema = new Schema({
name: {
type: String
},
type: {
type: String
},
payers: [PayerSchema]
});
const UserSchema = new Schema({
name: {
type: String,
required: [true, 'User name field is required']
},
bags: [BagSchema]
});
module.exports = mongoose.model('User', UserSchema);
我能够为新用户创建CRUD控制器方法,但我仍然不确定:
查看我的控制器用户/行李/参与者方法:
const User = require('../models/userModel');
getAllUserBags: (req, res, next) => {
User.findById({ _id: req.params.id }).then((user) => {
res.send(user.bags);
})
.catch(next);
},
getOneUserBag: (req, res, next) => {
console.log(req.params.bagid);
User.find({ 'bags._id': req.params.bagid}, {"bags.$" : 1}).then((obj) => {
res.send(obj);
})
.catch(next);
},
createBag: (req, res, next) => {
let bag = req.body.bag;
User.findOneAndUpdate(
{_id: req.body.id},
{$push: {bags: bag}
}).then(() => {
//Unnecessary - just to return update user with new bag.
User.findOne({_id: req.body.id}).then((user) => {
res.send(user);
})
}).catch(next);
},
addPayer: (req, res, next) => {
let payer = req.body.payer;
User.find(
{'bags._id': req.params.bagid},
{"bags.$" : 1},
{$push: {payers: payer}
}).then((obj) => {
console.log(obj);
//Unnecessary - just to return update user with new bag.
// User.findOne({_id: req.body.id}).then((user) => {
// res.send(user);
// })
}).catch(next);
}
感谢您的帮助
答案 0 :(得分:1)
根据我们讨论的内容,只要确保一个User
文档不超过MongoDB文档的16MB限制,您的User
架构就足以满足您的要求。
为特定用户创建一个新包(我能够这样做,但不确定它是否正确)
你很好。但是,有一些改进:
createBag: (req, res, next) => {
User.findByIdAndUpdate(req.body.id, {
$push: { bags: req.body.bag }
}, {
new: true // this will make the query getting the updated document
})
.then(user => {
res.json(user);
})
.catch(next);
})
为特定用户在特定行李中创建新参与者。 (addPayer方法错误需要帮助)
由于您决定嵌套'行李,bag.id
可能会在User
个文档中重复。请参阅this以了解可能性。因此,我建议您使用userId
和bagId
:
getOneUserBag: (req, res, next) => {
User.findOne({
_id: req.params.userId,
bags._id: req.params.bagId
})
.then(user => {
if (!user) res.status(404).end();
let bag = user.bags.id(req.params.bagId);
res.json(bag);
})
.catch(next);
}
addPayer: (req, res, next) => {
User.findOneAndUpdate({
_id: req.params.userId,
bags: $elemMatch: {
_id: req.params.bagId
}
}, {
$push: { 'bags.$.payers': req.body.payer } // Use 'positional $' operator along with $elemMatch in the query to update only the matched bag
}, {
new: true // Do not forget the 'new' options to get the updated document
})
.then(user => {
if (!user) res.status(404).end();
res.json(user);
})
.catch(next);
}
并在路由器中
router.get('/users/:userId/bags/:bagId', getOneUserBag);
router.post('/users/:userId/bags/:bagId/payers', addPayer);
在getAllUserBags()
中,您对User.findById()
使用了错误的语法:
getAllUserBags: (req, res, next) => {
User.findById(req.params.id) // Not { _id: req.params.id }
.then((user) => {
res.json(user.bags);
})
.catch(next);
}