我是NodeJS编程的新手,正在寻找有关如何在json Object中填充Object Array类型的响应属性的解决方案。
以下是我服务的样本回复 -
{
"Roles": [
"5b7fd72537651320a03494f8",
"5b7fdc06e3fcb037d016e26a"
],
"_id": "5b8e530be2d4630fd4f4b34a",
"Username": "ctucker",
"FirstName": "Chris",
"LastName": "Tucker",
"Email": "[email protected]",
"createdAt": "2018-09-04T09:40:27.091Z",
"updatedAt": "2018-09-04T09:40:27.091Z",
"__v": 0
}
我想用实际名称而不是ID来填充Roles数组属性中的ObjectId。
我该怎么做呢
以下是方法,我已经定义了User和Roles架构
用户模型
const userSchema = new mongoose.Schema({
Username: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
FirstName: {
type: String
},
LastName: {
type: String
},
Email: {
type: String,
required: true,
minlength: 5,
maxlength: 255
},
Password: {
type: String,
required: true,
minlength: 5,
maxlength: 1024
},
Roles: [{type: mongoose.Schema.Types.ObjectId, ref: Roles}],
Active: {type: Boolean, default: true},
SuperUser: {type: Boolean, default: false}
},{
timestamps: true
});
角色模型
const rolesSchema = new mongoose.Schema({
RoleName: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
Description: {
type: String
},
Active: {type: Boolean, default: true}
}, {
timestamps: true
});
创建用户
router.post('/', [auth, admin], async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ Username: req.body.Username });
if (user) return res.status(400).send('User with username: ', req.body.Username, 'already exists. Please try with any other username');
let roleInput = [];
if(req.body.Roles !== null) {
req.body.Roles.forEach( async (element) => {
objectId = mongoose.Types.ObjectId(element);
roleInput.push(objectId);
});
}
console.log('Role info ', roleInput);
user = new User(_.pick(req.body, ['Username', 'FirstName', 'LastName' ,'Email', 'Password', 'Active','SuperUser']));
console.log('User Input => ', user);
const salt = await bcrypt.genSalt(10);
user.Password = await bcrypt.hash(user.Password, salt);
roleInput.forEach( async (objectId) => {
user.Roles.push(objectId);
});
console.log('User Input after role addition => ', user);
await user.save();
const token = user.generateAuthToken();
res.header('x-auth-token', token).send(_.pick(user, ['_id', 'FirstName', 'LastName' ,'Email', 'Roles']));
});
我想在响应中获取RoleName而不是ObjectId。在这方面的任何帮助将不胜感激。
忘了提到我已经尝试过使用populate方法,但是我看到了以下异常。
我如何使用populate方法 -
router.get('/', auth, (req, res, next) => {
var request_params = url.parse(req.url,true).query;
var searchQuery = (request_params.mode === 'active') ? {'Active': true} : {};
User.find(searchQuery)
.populate('Roles')
.select(['-Password', '-Active', '-SuperUser'])
.then((users) => {
res.send(users);
}, (error) => {
next(error);
});
});
例外 -
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>Schema hasn't been registered for model "[object Object]".
Use mongoose.model(name, schema)</h1>
<h2></h2>
<pre>MissingSchemaError: Schema hasn't been registered for model "[object Object]".
Use mongoose.model(name, schema)
at new MissingSchemaError (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\error\missingSchema.js:20:11)
at NativeConnection.Connection.model (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\connection.js:791:11)
at getModelsMapForPopulate (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\model.js:4016:20)
at populate (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\model.js:3505:21)
at _populate (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\model.js:3475:5)
at utils.promiseOrCallback.cb (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\model.js:3448:5)
at Object.promiseOrCallback (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\utils.js:232:14)
at Function.Model.populate (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\model.js:3447:16)
at cb (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\lib\query.js:1678:17)
at result (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\utils.js:414:17)
at executeCallback (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\utils.js:406:9)
at handleCallback (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\utils.js:128:55)
at cursor.close (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\operations\cursor_ops.js:211:62)
at handleCallback (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\utils.js:128:55)
at completeClose (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\cursor.js:887:14)
at Cursor.close (C:\Vijay-Docs\Personal\vuejs-ws\AgileCenter\agilecenterservices\node_modules\mongoose\node_modules\mongodb\lib\cursor.js:906:10)</pre>
</body>
</html>
简单使用猫鼬populate()
功能
const user = await User.findOne().populate('Roles');
// output => user.Roles // will be array of mongo documents
干杯
您可以使用Mongoose的populate填充RoleName
而不是ObjectId
refs
Mongoose有一个更强大的替代方法叫做populate(),它允许你引用其他集合中的文档。
'use strict';
let user = await User.findOne({
Username: req.body.Username
}).populate('Roles');
if (user && user.Roles.length > 0) {
for (let role of user.Roles) {
console.log(role.RoleName);// logs `RoleName`
}
}
理解了这个问题。
在用户模式定义中,我还必须定义角色模式。
const rolesSchema = new mongoose.Schema({
RoleName: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
Description: {
type: String
},
Active: {type: Boolean, default: true}
}, {
timestamps: true
});
const Roles = mongoose.model('Roles', rolesSchema);
const userSchema = new mongoose.Schema({
Username: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
FirstName: {
type: String
},
LastName: {
type: String
},
Email: {
type: String,
required: true,
minlength: 5,
maxlength: 255
},
Password: {
type: String,
required: true,
minlength: 5,
maxlength: 1024
},
Roles: [{type: mongoose.Schema.Types.ObjectId, ref: 'Roles'}],
Active: {type: Boolean, default: true},
SuperUser: {type: Boolean, default: false}
},{
timestamps: true
});
在用户模式中添加角色模式定义后,邮递员的响应会填充RoleName作为响应。
{
"Roles": [
{
"RoleName": "AC-User"
},
{
"RoleName": "AC-PMLead"
}
],
"_id": "5b8e48e2f3372a098c6e5346",
"Username": "mcmillan",
"FirstName": "McMillan",
"LastName": "McMillan",
"Email": "[email protected]",
"createdAt": "2018-09-04T08:57:07.029Z",
"updatedAt": "2018-09-04T08:57:07.029Z",
"__v": 0
}