mongoose - 如何在 getter 中获取对象而不是对象引用?
mongoose - How to get an object instead of an object reference in a getter?
我在 Node.js 中用猫鼬创建了一个 API。我将我的数据保存在一个集合事务中,它提供了一些来自其他集合对象的引用:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const transactionSchema = new Schema({
status: String,
_user: { type: Schema.Types.ObjectId, ref: 'User' },
_borne: { type: Schema.Types.ObjectId, ref: 'Borne' },
createdAt: Date,
updatedAt: Date
});
当我查询交易时,我会得到 Borne 对象而不是它的 ID,因为它保存在我的数据库中。我不直接将其保存为 Borne 对象,因为某些更改可能会出现在我的 Borne(或 User)对象中,我希望将其保存在每个 Transaction 对象上。
所以我尝试使用虚拟或路径(覆盖),但它并没有改变我的输出,我也不知道这样做是否正确:
// In this example, I try to change the status output by "new status" to test if it works, and it doesn't
transactionSchema.path('status')
.get(function(value) {
return "new status";
})
});
输出与之前相同。
编辑:Populate
是解决方案,但不起作用
目前,我正在 index.js
文件中加载我的模型:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const apn = require('apn');
const keys = require('./config/keys');
require('./app/models/Borne');
require('./app/models/User');
require('./app/models/Transaction');
require('./app/models/Comment');
require('./app/models/Notification');
const app = express();
const apnProvider = new apn.Provider(keys.apns.options);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
mongoose.connect(keys.mongoURI, (err, database) => {
if (err) return console.log(err);
require('./app/routes')(app);
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log('We are live on ' + PORT);
});
});
那么,这里是模型的例子:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const transactionSchema = new Schema({
status: String,
details: {
amount: { type: Number }, // money
quantity: { type: Number }, // power consumed
date: { type: Date },
city: { type: String }
},
logs: [
{
state: String,
date: Date
}
],
_user: { type: Schema.Types.ObjectId, ref: 'User' },
_borne: { type: Schema.Types.ObjectId, ref: 'Borne' },
createdAt: Date,
updatedAt: Date
});
mongoose.model('transactions', transactionSchema);
最后,这里是我调用的populate
。它不起作用:
const mongoose = require('mongoose');
const User = mongoose.model('users');
const Transaction = mongoose.model('transactions');
const Borne = mongoose.model('bornes');
const Comment = mongoose.model('comments');
module.exports = app => {
app.get('/v1/user/:id/transactions', async (req, res) => {
const ObjectID = require('mongodb').ObjectID;
var id = req.params.id;
var existingUser;
if (req.params.id == 'me' && req.user) {
id = req.user.id;
existingUser = req.user;
} else {
existingUser = await User.findOne({ _id: new ObjectID(id) });
}
if (existingUser) {
const transactions = await Transaction.find({
_user: new ObjectID(id),
status: { $nin: ['booked', 'charging', 'charged', 'left'] }
}).populate('_user').populate('_borne').sort({ updatedAt: -1 });
// ...
res.status(200);
res.send({
statusCode: 200,
data: transactions
});
}
});
};
根据MongoDB Documentation,如果要获取引用指向的对象,必须"manually"进行第二次查询。
但是 Mongoose
提供了 populate
方法,允许您用正确的文档替换引用。
Population is the process of automatically replacing the specified
paths in the document with document(s) from other collection(s).
因此,在您的情况下,您可以这样做:
var transactionModel = mongoose.model('Transaction', transactionSchema);
transactionModel
.find({})
.populate('_user')
.populate('_borne')
.exec((err, transaction) => {
if (err) return handleError(err);
// deal with your transaction
});
编辑
我刚读了你的编辑,你能帮我试试吗:
删除 index.js
文件中的所有 require('./app/models/xxx')
。
在模型的末尾:
module.exports = mongoose.model('xxx', xxxSchema);
然后在你的路线/控制器中:
const User = require('/app/models/users');
const Borne = require('/app/models/borne');
const Transaction = require('/app/models/transaction');
因此您的模型与模式同时创建,您确定这是正确的顺序。
希望对您有所帮助,
最好的问候
我认为要有一个快速而健壮的查询,你应该看看 Aggregate Query 和 moongodb。
查询交易集合(匹配正确的_id),然后展开_user 属性,查找用户集合(类似于SQL中的JOIN),展开_born集合,查找出生的集合。
这样看起来有点复杂,但它非常强大和快速。
我在 Node.js 中用猫鼬创建了一个 API。我将我的数据保存在一个集合事务中,它提供了一些来自其他集合对象的引用:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const transactionSchema = new Schema({
status: String,
_user: { type: Schema.Types.ObjectId, ref: 'User' },
_borne: { type: Schema.Types.ObjectId, ref: 'Borne' },
createdAt: Date,
updatedAt: Date
});
当我查询交易时,我会得到 Borne 对象而不是它的 ID,因为它保存在我的数据库中。我不直接将其保存为 Borne 对象,因为某些更改可能会出现在我的 Borne(或 User)对象中,我希望将其保存在每个 Transaction 对象上。
所以我尝试使用虚拟或路径(覆盖),但它并没有改变我的输出,我也不知道这样做是否正确:
// In this example, I try to change the status output by "new status" to test if it works, and it doesn't
transactionSchema.path('status')
.get(function(value) {
return "new status";
})
});
输出与之前相同。
编辑:Populate
是解决方案,但不起作用
目前,我正在 index.js
文件中加载我的模型:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const apn = require('apn');
const keys = require('./config/keys');
require('./app/models/Borne');
require('./app/models/User');
require('./app/models/Transaction');
require('./app/models/Comment');
require('./app/models/Notification');
const app = express();
const apnProvider = new apn.Provider(keys.apns.options);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
mongoose.connect(keys.mongoURI, (err, database) => {
if (err) return console.log(err);
require('./app/routes')(app);
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log('We are live on ' + PORT);
});
});
那么,这里是模型的例子:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const transactionSchema = new Schema({
status: String,
details: {
amount: { type: Number }, // money
quantity: { type: Number }, // power consumed
date: { type: Date },
city: { type: String }
},
logs: [
{
state: String,
date: Date
}
],
_user: { type: Schema.Types.ObjectId, ref: 'User' },
_borne: { type: Schema.Types.ObjectId, ref: 'Borne' },
createdAt: Date,
updatedAt: Date
});
mongoose.model('transactions', transactionSchema);
最后,这里是我调用的populate
。它不起作用:
const mongoose = require('mongoose');
const User = mongoose.model('users');
const Transaction = mongoose.model('transactions');
const Borne = mongoose.model('bornes');
const Comment = mongoose.model('comments');
module.exports = app => {
app.get('/v1/user/:id/transactions', async (req, res) => {
const ObjectID = require('mongodb').ObjectID;
var id = req.params.id;
var existingUser;
if (req.params.id == 'me' && req.user) {
id = req.user.id;
existingUser = req.user;
} else {
existingUser = await User.findOne({ _id: new ObjectID(id) });
}
if (existingUser) {
const transactions = await Transaction.find({
_user: new ObjectID(id),
status: { $nin: ['booked', 'charging', 'charged', 'left'] }
}).populate('_user').populate('_borne').sort({ updatedAt: -1 });
// ...
res.status(200);
res.send({
statusCode: 200,
data: transactions
});
}
});
};
根据MongoDB Documentation,如果要获取引用指向的对象,必须"manually"进行第二次查询。
但是 Mongoose
提供了 populate
方法,允许您用正确的文档替换引用。
Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s).
因此,在您的情况下,您可以这样做:
var transactionModel = mongoose.model('Transaction', transactionSchema);
transactionModel
.find({})
.populate('_user')
.populate('_borne')
.exec((err, transaction) => {
if (err) return handleError(err);
// deal with your transaction
});
编辑
我刚读了你的编辑,你能帮我试试吗:
删除 index.js
文件中的所有 require('./app/models/xxx')
。
在模型的末尾:
module.exports = mongoose.model('xxx', xxxSchema);
然后在你的路线/控制器中:
const User = require('/app/models/users');
const Borne = require('/app/models/borne');
const Transaction = require('/app/models/transaction');
因此您的模型与模式同时创建,您确定这是正确的顺序。
希望对您有所帮助,
最好的问候
我认为要有一个快速而健壮的查询,你应该看看 Aggregate Query 和 moongodb。
查询交易集合(匹配正确的_id),然后展开_user 属性,查找用户集合(类似于SQL中的JOIN),展开_born集合,查找出生的集合。
这样看起来有点复杂,但它非常强大和快速。