2014-09-10 47 views
3

我正在运行一个MongoDB,通过Mongoose访问来存储用户记录。我在服务器上也有下划线。我有一个RESTful API和一个从数据库返回一个集合(对象数组)的路由。我想将完整集合返回给客户端,但是从每个对象中删除密码元素,以便不会发送到客户端。在任何人说什么之前,我将使用bcrypt在最终版本中使用salt并散列密码:)underscore.js .keys和.omit不按预期工作

今天,我只在数据库中有一个用户'administrator'的条目。下面是我的路线代码:

app.get('/users', function(req, res) { 
    User.find().sort({'userName': 'ascending'}).exec(function(err, data) { 
    _.each(data, function (element, index, list) { 
     console.log('userName=' + element.userName); 
     console.log('password=' + element.password); 
     delete element.password; 
     console.log('keys: ' + _.keys(element)); 
     console.log('password=' + element.password); 
     console.log(_.omit(element, 'password')); 
    }); 
    res.json(data); 
    }); 
}); 

我所得到的发送回浏览器:

[{"_id":"54058e6eb53dd60730295f59","modifiedOn":"2014-09-01T15:19:10.012Z", 
"userName":"administrator","password":"stackoverflow","role":"administrator", 
"__v":0,"createdBy":"54058e6eb53dd60730295f59","createdOn":"2014-09-01T15:19:10.004Z", 
"previousLogins":[],"accountIsLocked":false,"loginAttempts":0}] 

我们哪罚款,因为res.json(data)声明就发送原始data回浏览器 - 这不是问题。问题是delete(以及如果我使用.omit)似乎不适合我的收藏!正如你可以看到有很多的console.log进行调试,这里是获取输出:

userName=administrator 
password=stackoverflow 
keys: $__,isNew,errors,_maxListeners,_doc,_pres,_posts,save,_events 
password=stackoverflow 
{ _id: 54058e6eb53dd60730295f59, 
    modifiedOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST), 
    userName: 'administrator', 
    password: 'stackoverflow', 
    role: 'administrator', 
    __v: 0, 
    createdBy: 54058e6eb53dd60730295f59, 
    createdOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST), 
    previousLogins: [], 
    accountIsLocked: false, 
    loginAttempts: 0 } 

_.keys输出显示键(?我从一个物体原型假设),我没有看到,当我console.log(element)但没有可通过element.key访问的密钥。

任何想法,为什么我看到这种行为?

+0

这真的很奇怪。请参阅'_.keys'不应该访问对象原型的属性。 'console.log(element .__ proto __。constructor)'显示什么? – raina77ow 2014-09-10 14:04:04

+0

是的,我看起来也很奇怪! 'onsole.log(element .__ proto __。constructor)'输出大量条目......这里是一个pastebin链接:[link](http://pastebin.com/vUkFabHY) – 2014-09-10 14:58:53

回答

10

的问题是,data传入exec回调函数实际上是一个Document对象 - 这可以被认为是由猫鼬创造的Models的集合。这些对象有很多有用的方法,他们记得与db等的连接 - 但是你将无法将它们作为普通对象来处理。

解决方案是指导猫鼬是你真正想要纯JS对象与lean()查询的结果是:

User.find().sort({'userName': 'ascending'}).lean().exec(function(err, data) { 
    // process the data 
}); 

另外,你应该能够把每一个模型转换为普通物体.toObject()方法,然后过滤它:

var filtered = _.map(data, function(model) { 
    return _.omit(model.toObject(), 'password'); 
}); 
res.json(filtered); 

...但我宁愿使用第一种方法。 )

+0

raina77ow,完美的工作,非常感谢! – 2014-09-10 15:50:36

+0

如果您可以使用ES6,那么您可以更轻松地做到这一点。 let normalObject = {... data ['_ doc']} – Freddie 2018-02-16 11:58:19