2012-06-22 2 views
45

У меня есть следующий простой Шма:Как исключить некоторые поля из документа

var userSchema = new Schema({ 
    name : String, 
    age: Number, 
    _creator: Schema.ObjectId 
    }); 

    var User = mongoose.model('User',userSchema); 

То, что я хочу сделать, это создать новый документ и вернуться к клиенту, но я хочу, чтобы исключить поле «создатель» от одного:

app.post('/example.json', function (req, res) { 
    var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'}); 
    user.save(function (err) { 
     if (err) throw err; 

     res.json(200, {user: user});  // how to exclude the _creator field? 
    }); 
}); 

в конце я хочу, чтобы отправить новый созданный пользователем без _creator поля:

{ 
    name: 'John', 
    age: 45 
} 

Можно ли сделать без дополнительной находки для мангуста?

PS: Это желательно сделать его

+0

создать новый объект JSon без указанного поля и вернуть его. В чем проблема? –

ответ

62

Другой способ справиться это на уровне схемы, чтобы переопределить JSON для модели.

UserSchema.methods.toJSON = function() { 
    var obj = this.toObject() 
    delete obj.passwordHash 
    return obj 
} 

Я наткнулся на этот вопрос искал способ, чтобы исключить хэш пароля из JSON я служил клиенту, и select: false сломал мою функцию verifyPassword, потому что он не извлечь значение из базы данных на всех.

+0

Спасибо! Это то, что мне нужно! – Erik

+6

Попробуйте использовать UserSchema.set ('toJSON', { \t \t преобразования: функции (DOC, RET, опции) { \t \t \t удалить ret.password; \t \t \t возвращение в отставке; \t \t} \t}); – Xerri

+0

Просто будьте осторожны с кем-либо, копирующим этот код, obj должен иметь перед ним инструкцию var, иначе это приведет к утечке глобальной ссылки. –

6

Вы можете позвонить toObject() на документ, чтобы преобразовать его в обычный объект JS, что вы можете свободно изменять:

user = user.toObject(); 
delete user._creator; 
res.json(200, {user: user}); 
+0

Спасибо за ответ, могу ли я определить поля, которые никогда не возвращаются на уровне схемы? – Erik

+4

Вы можете скрыть поля схемы по умолчанию, включив в определение поля 'select: false'. – JohnnyHK

+0

Это гораздо лучший способ сделать это, чем изменить сериализацию по умолчанию для всех объектов. –

17

Пройдите свой вопрос, когда я пытался найти аналогичный ответ с pymongo. Оказывается, что в оболочке mongo с вызовом функции find() вы можете передать второй параметр, который указывает, как выглядит документ результатов. Когда вы передаете словарь с значением атрибута равным 0, вы исключаете это поле во всем документе, который выходит из этого запроса.

В вашем случае, например, запрос будет как:

db.user.find({an_attr: a_value}, {_creator: 0}); 

Это исключит параметр _creator для вас.

В pymongo функция find() почти такая же. Не уверен, как это перевести на мангуста. Я думаю, что это лучшее решение, сравнимое с ручным удалением полей.

Надеюсь, это поможет.

+0

Хотя другие могут работать, это кажется правильным ответом на меня. Работал для меня. – abritez

+0

Это может работать в некоторых случаях, но не в большинстве, потому что даже если вы не хотите отображать поле, есть хороший шанс, что вы хотите, чтобы он работал в бэкэнд. Проблема с этим решением и многие другие похожи на то, что данное поле никогда не извлекается из базы данных. Если у вас есть другие рассчитанные или виртуальные поля, которые зависят от него, они не будут установлены должным образом. – jfmatt

+2

Обход Мангуста, кажется, является рекомендуемым способом делать вещи в Мангусте в эти дни. Давайте зададимся вопросом, если Mongoose полностью выполнит эту задачу. – nottinhill

51

Документально способ

UserSchema.set('toJSON', { 
    transform: function(doc, ret, options) { 
     delete ret.password; 
     return ret; 
    } 
}); 

UPDATE - Вы можете использовать белый список:

UserSchema.set('toJSON', { 
    transform: function(doc, ret, options) { 
     var retJson = { 
      email: ret.email, 
      registered: ret.registered, 
      modified: ret.modified 
     }; 
     return retJson; 
    } 
}); 
+7

или, если ваш уже подчеркивают/lodash, вы можете использовать '_.pick' UserSchema.set ('toJSON', { преобразования: функция (Doc, RET, опции) { возвращение _.pick (в отставке, 'email', 'registered', 'modified') } }) –

+0

@xerri - где это документировано? я вижу toJSON, но с трудностью найти преобразование –

+0

@xerri - нашел его, просто запутался, так как документы находятся под toObject не toJSON ==> http://mongoosejs.com/docs/api.html#document_Document-toObject –

9

Я хотел бы использовать lodash Utilities .pick() или .omit()

var _ = require('lodash'); 

app.post('/example.json', function (req, res) { 
    var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'}); 
    user.save(function (err) { 
     if (err) throw err; 
     // Only get name and age properties 
     var userFiltered = _.pick(user.toObject(), ['name', 'age']); 
     res.json(200, {user: user}); 
    }); 
}); 

Другой пример wou ld be:

var _ = require('lodash'); 

app.post('/example.json', function (req, res) { 
    var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'}); 
    user.save(function (err) { 
     if (err) throw err; 
     // Remove _creator property 
     var userFiltered = _.omit(user.toObject(), ['_creator']); 
     res.json(200, {user: user}); 
    }); 
}); 
1

Я пользуюсь Mongoosemask и очень доволен этим.

он поддерживает скрытие и обнажая свойства с другими названиями, основанные на Вашей потребности

https://github.com/mccormicka/mongoosemask

вар maskedModel = mongomask.mask (модель, [ 'имя', 'возраст']); // И все готово.

1

Следуя документацию MongoDB, вы можете исключить поля, передавая второй параметр для запроса как:

User.find({_id: req.user.id}, {password: 0}) 
     .then(users => { 
      res.status(STATUS_OK).json(users); 
     }) 
     .catch(error => res.status(STATUS_NOT_FOUND).json({error: error})); 

В этом случае пароль будет исключен из запроса.

шрифта: https://docs.mongodb.com/v2.8/tutorial/project-fields-from-query-results/#return-all-but-the-excluded-field

Смежные вопросы