MongoDB: вывести «id» вместо «_id» - PullRequest
47 голосов
/ 12 августа 2011

Я использую mongoose (узел), как лучше выводить id вместо _id?

Ответы [ 11 ]

84 голосов
/ 27 декабря 2012

Учитывая, что вы используете Mongoose, вы можете использовать 'virtuals', которые по сути являются поддельными полями, которые создает Mongoose.Они не хранятся в БД, они просто заполняются во время выполнения:

// Duplicate the ID field.
Schema.virtual('id').get(function(){
    return this._id.toHexString();
});

// Ensure virtual fields are serialised.
Schema.set('toJSON', {
    virtuals: true
});

Каждый раз, когда вызывается toJSON для модели, которую вы создаете из этой схемы, он будет содержать поле 'id', соответствующееполе _id генерирует Mongo.Точно так же вы можете установить поведение для toObject таким же образом.

См .:

Вы можете абстрагироватьсяэто в BaseSchema все ваши модели затем расширяют / вызывают, чтобы сохранить логику в одном месте.Я написал выше при создании приложения Ember / Node / Mongoose, поскольку Ember действительно предпочитает иметь поле 'id' для работы.

29 голосов
/ 12 августа 2011

Я создаю метод toClient () на моих моделях, где я делаю это.Это также хорошее место для переименования / удаления других атрибутов, которые вы не хотите отправлять клиенту:

Schema.method('toClient', function() {
    var obj = this.toObject();

    //Rename fields
    obj.id = obj._id;
    delete obj._id;

    return obj;
});
23 голосов
/ 10 декабря 2013
//Transform
Schema.options.toJSON.transform = function (doc, ret, options) {
  // remove the _id of every document before returning the result
  ret.id = ret._id;
  delete ret._id;
  delete ret.__v;
}

есть свойство "Schema.options.toObject.transform", чтобы сделать обратное, или вы можете просто установить его как виртуальный идентификатор.

22 голосов
/ 23 декабря 2015

Начиная с Mongoose v4.0 часть этой функциональности поддерживается из коробки . Больше не требуется вручную добавлять виртуальное поле id, как объясняет @Pascal Zajac.

Mongoose по умолчанию присваивает каждой вашей схеме идентификатор виртуального геттера который возвращает поле документов _id, приведенное к строке, или в случае ObjectIds, его hexString. Если вы не хотите, чтобы идентификатор получателя был добавлен в ваша схема, вы можете отключить его, передав эту опцию в схеме время строительства. Источник

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

Schema.set('toJSON', {
    virtuals: true
});
20 голосов
/ 23 января 2014

Вот альтернативная версия ответа, предоставленная @ user3087827. Если вы обнаружите, что schema.options.toJSON не определено, вы можете использовать:

schema.set('toJSON', {
     transform: function (doc, ret, options) {
         ret.id = ret._id;
         delete ret._id;
         delete ret.__v;
     }
}); 
8 голосов
/ 13 марта 2017

Я использовал это:

schema.set('toJSON', {
  virtuals: true,
  versionKey:false,
  transform: function (doc, ret) {   delete ret._id  }
});

Я думаю, было бы замечательно, если бы они автоматически подавляли _id, когда виртуалы истинны.

4 голосов
/ 18 ноября 2016

Я создал простой в использовании плагин для этой цели, который я применяю для всех своих проектов и для всех глобальных схем.Он преобразует _id в id и также обрезает параметр __v.

Так что он преобразует:

{
  "_id": "400e8324a71d4410b9dc3980b5f8cdea",
  "__v": 2,
  "name": "Item A"
}

В более простой и понятный:

{
  "id": "400e8324a71d4410b9dc3980b5f8cdea",
  "name": "Item A"
}

Использование в качестве глобального плагина:

const mongoose = require('mongoose');
mongoose.plugin(require('meanie-mongoose-to-json'));

Или для конкретной схемы:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const MySchema = new Schema({});
MySchema.plugin(require('meanie-mongoose-to-json'));

Надеюсь, это кому-нибудь поможет.

1 голос
/ 10 ноября 2018

Если вы используете lodash, чтобы выбрать нужные элементы, это будет работать для вас.

UserSchema.virtual('id').get(function(){
  return this._id.toHexString();
});

UserSchema.set('toObject', { virtuals: true })

UserSchema.methods.toJSON = function() {
  return _.pick( 
    this.toObject(), 
    ['id','email','firstName','lastName','username']
  );
0 голосов
/ 24 мая 2019

Перезаписать метод по умолчанию toJSON новым:

schema.method('toJSON', function () {
   const { __v, _id, ...object } = this.toObject();
   object.id = _id;
   return object;
});
0 голосов
/ 24 октября 2017

Вы также можете использовать функцию агрегирования при поиске элементов для возврата.$ project позволит вам создать поля, которые вы можете сделать, и назначить их _id.

<model>.aggregate([{$project: {_id: 0, id: '$_id'}], (err, res) => {
 // 
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...