我对Node.js开发很新。尽管我对异步函数有一些经验,但回调仍然让我感到很沮丧。
我正在使用mongoose的.find()函数来搜索数据库中的Users集合。问题是我也想显示这些用户,但我不想显示数据库中的所有可用属性。
...
function(req,res){
User.find(function(err,users){
res.json(users.convertToOtherModel());
})
}
...
这就是我目前在数据库中获取所有用户的方式,但这也会返回密码和其他敏感信息。我想知道最有效的方法是将这些数据“转换”到同一个对象中,而不需要一些属性或改变属性,比如添加一个由firstName + lastName组成的“fullName”;
因此,在返回所有用户时,我希望有类似
的内容Microsoft.Azure.Documents.BadRequestException:
{"Errors":["Cross partition query only supports 'VALUE <AggreateFunc>' for aggregates."]}
---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x800A0B00
不确定“convertToOtherModel”功能是否可以放在某个地方以便它适用于用户......但是如何做到这一点的任何想法都会有所帮助!
答案 0 :(得分:2)
你可以这样做,只返回一些属性:
function filterUser(user) {
let { property1, property2 } = user;
return { property1, property2 };
}
res.json( users.map(filterUser) );
或者使用lodash的更便携方式:
res.json( users.map(user => _.pick(user, ['prop1', 'prop2']));
请参阅:https://lodash.com/docs/4.17.4#pick
要使用lodash版本,首先需要添加:
const _ = require('lodash');
代码,并在项目目录中运行:
npm install lodash --save
答案 1 :(得分:2)
personSchema
.virtual('fullName')
.get(function () {
return this.name.first + ' ' + this.name.last;
})
.set(function (v) {
this.name.first = v.substr(0, v.indexOf(' '));
this.name.last = v.substr(v.indexOf(' ') + 1);
})
对于类似FullName
的内容,您可以创建virtual
架构。
您必须选择要输出的列,我不确定您是否可以专门将列列入黑名单(所有列减去密码列)
答案 2 :(得分:1)
您可以将第二个参数传递给find()
,并指定您想要或不想返回的字段,而不是使查询返回所有字段
User.find({}, {password: 0}, function(error, users) {
console.log(users)
})
您还可以使用aggregation framework
并通过联合不同字段的值来创建新字段
User.aggregate([
{$project: {
username: '$username',
fullName: {$concat: ['$firstName', ' ', '$lastName']}
}}
], function(error, users) {
console.log(users)
})
答案 3 :(得分:1)
覆盖用户架构的toJSON
方法。
UserSchema.methods.toJSON = function () {
var user = this;
// Modify your document object here
return { fullName: user.firstName + " " + user.lastName }
// Pick other fields too if you want
// _.pick(user, ["otherField"]);
};
然后像这样发送 -
User.find(function(err,users){
res.json(users);
})