我是JavaScript和Mongoose的新手。我正在使用express,mongoose和node.js构建一个小项目。 我有一个猫鼬模型 - 具有交易数组
的客户端 var Client = mongoose.model('Client', {
name: {
type: String,
required: true,
minlength: 1
},
email: {
type: String
},
phone: {
type: Number
},
createdAt: {
type: Number,
default: null
},
transactions: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Transaction' }],
_creator: {
type: mongoose.Schema.Types.ObjectId,
required: true
}
});
module.exports = {Client};
这是交易模型:
var Client = require('./client');
var Transaction = mongoose.model('Transaction',{
_creator : { type: mongoose.Schema.Types.ObjectId, ref: 'Client' },
amount : {type: Number, min: 0},
date : {type: Number,default: null},
total: {type: Number,default: null}
});
module.exports = {Transaction};
当我发布新事务时,它会通过并保存在db:
中 app.post('/clients/:id/transactions', authenticate, (req, res) => {
var id = req.params.id;
var transaction = new Transaction({
amount: req.body.amount,
date: new Date().getTime(),
total: req.body.total,
_creator: req.params.id
})
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
transaction.save().then((doc) => {
Client.findOneAndUpdate({
_id: id,
_creator: req.user._id,
transactions: req.body.transaction
});
res.send(doc);
}, (e) => {
res.status(400).send(e);
});
});
我还能够获取与客户关联的所有交易:
app.get('/clients/:id/transactions', authenticate, (req, res) => {
var id = req.params.id;
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
Transaction.find({
_creator: id
}).then((transactions) => {
res.send({transactions});
}).catch((e) => {
res.status(400).send();
});
});
但是当我对'/ clients'进行GET调用时 - 事务数组为空:
{
"clients": [
{
"_id": "1095d6de3867001108b803",
"name": "Peter",
"email": "peter@gmail.com",
"phone": 1232321,
"_creator": "5321df6d57868ec7001108b801",
"__v": 0,
"transactions": [],
"createdAt": null
} ]
}
这是对/ clients
的GET调用 app.get('/clients', authenticate, (req, res) => {
Client.find({
_creator: req.user._id,
})
.populate('transactions.transaction')
.then((clients) => {
res.send({clients});
}, (e) => {
res.status(400).send(e);
console.log('Unable to get clients', e);
})
});
我知道我可能做错了但我不知道在哪里需要找错。请帮忙!
答案 0 :(得分:1)
所以首先我不知道客户端模型代表什么_creator
键,它可能是有一些客户的用户标识符,但如果我错了请纠正我。
老实说,我不知道你为什么要进行双向文档连接,(保持客户端在事务中,并在客户端保持事务)在我看来第一个选项对于mongodb更好,并且使用它可以轻松获得事务列表查找或mongodb聚合,但您无法使用populate
获取数据。
在第二个选项中,您需要记住一个文档最多可以有16MB。并且在一个阵列中保留数千个事务并不能很好地提高性能。考虑一下你有5000个事务的例子,你想要显示带分页的列表(每页50个记录),使用数组选项你必须获得整个文档,并将数组拼接到50个记录。在第一个选项中,您可以使用mongodb skip和limit。请考虑一下。
回答问题,你在做的错误就在这里: transaction.save()。then((doc)=> {
Client.findOneAndUpdate({
_id: id,
_creator: req.user._id,
transactions: req.body.transaction
});
res.send(doc);
这里您没有确切说明本文档应如何更新。
使用mongodb findAndModify方法在方法findOneAndUpdate中进行Mongoose。但params用于更新。 https://docs.mongodb.com/manual/reference/method/db.collection.update/
还有文档说你有什么类似的: 查询#findOneAndUpdate([query],[doc],[options],[options.passRawResult],[options.strict],[callback])
因此,第一个query
param是mongo查询以在数据库中查找一个文档,下一个param是具有更新查询的对象,之后您可以在第三个参数中发送一些其他选项。所以你的代码应该是这样的:
transaction.save().then((doc) => {
Client.findOneAndUpdate({
_id: id,
_creator: req.user._id,
}, {
$addToSet: {
transactions: doc._id,
}
});
res.send(doc);
您可以使用addToSet
或push
将元素放入数组,但addToSet
避免重复数组。然后,我们将新的事务标识符推送到此数组中。毕竟你只填充transaction
键。
我希望我帮助过。如果您有任何疑问,请询问。
答案 1 :(得分:1)
我会在添加交易之前检查客户端是否存在。交易首先需要客户。
预先警告,我不是then
和catch
的粉丝,所以这个答案不会使用它。在处理多个异步操作时,我通常使用async.js。
无论如何,我会这样做
app.post('/clients/:id/transactions', authenticate, (req, res) => {
Client.findOne({ _id: req.params.id }, (err, client) => {
if (err)
return res.status(400).send(err);
if (!client)
return res.status(400).send(new Error('No client'));
Transaction.create({
amount: req.body.amount,
date: new Date(), // I don't think you need .getTime()
total: req.body.total,
_creator: client._id
}, (err, transaction) => {
if (err)
return res.status(400).send(err);
client.transactions.push(transaction._id);
client.save(err => {
if (err)
return res.status(400).send(err);
res.json(transaction);
});
});
});
});
最好也打开调试模式以查看您的查询:mongoose.set('debug', true)
。
您可能还会发现使用timestamps
option对事务架构比明确使用date
字段
为客户提供交易
app.get('/clients', authenticate, (req, res) => {
Client.find({ _creator: req.user._id }).populate('transactions').exec((err, clients) => {
if (err)
return res.status(400).send(err);
res.json(clients);
});
});