我是NodeJS编程的新手,正在寻找有关如何在JSON Object中填充对象数组类型的响应属性的解决方案。
以下是我的服务的示例响应-
{
"Roles": [
"5b7fd72537651320a03494f8",
"5b7fdc06e3fcb037d016e26a"
],
"_id": "5b8e530be2d4630fd4f4b34a",
"Username": "ctucker",
"FirstName": "Chris",
"LastName": "Tucker",
"Email": "ctucker@innovate.com",
"createdAt": "2018-09-04T09:40:27.091Z",
"updatedAt": "2018-09-04T09:40:27.091Z",
"__v": 0
}
我想用实际名称而不是ID填充Roles数组属性中的ObjectId。
我应该怎么做。
以下是方法,我已经定义了用户和角色架构
用户模型
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方法,但是看到以下异常。
我如何使用填充方法-
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>
答案 0 :(得分:0)
使用猫鼬populate()
函数简单
const user = await User.findOne().populate('Roles');
// output => user.Roles // will be array of mongo documents
欢呼
答案 1 :(得分:0)
您可以使用猫鼬的populate来填充RoleName
而不是ObjectId
裁判
猫鼬有一个更强大的替代方法,称为 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`
}
}
答案 2 :(得分:0)
理解了这个问题。
在用户架构定义中,我还必须定义角色架构。
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": "mcmillan@innovate.com",
"createdAt": "2018-09-04T08:57:07.029Z",
"updatedAt": "2018-09-04T08:57:07.029Z",
"__v": 0
}