web-dev-qa-db-fra.com

MongoDB: sortie 'id' au lieu de '_id'

J'utilise mangouste (noeud), quel est le meilleur moyen de sortir id à la place de _id?

42
Johnny

Je crée une méthode toClient () sur mes modèles où je le fais. C'est également un bon endroit pour renommer/supprimer d'autres attributs que vous ne voulez pas envoyer au client:

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

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

    return obj;
});
29
evilcelery

Étant donné que vous utilisez Mongoose, vous pouvez utiliser des "virtuels", qui sont essentiellement de faux champs créés par Mongoose. Ils ne sont pas stockés dans la base de données, ils sont simplement renseignés au moment de l'exécution:

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

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

Chaque fois que toJSON est appelé sur le modèle que vous créez à partir de ce schéma, il inclut un champ 'id' correspondant au champ _id généré par Mongo. De même, vous pouvez définir le comportement de toObject de la même manière. 

Voir: 

Vous pouvez résumer cela dans un BaseSchema tous vos modèles, puis étendre/invoquer pour garder la logique au même endroit. J'ai écrit ce qui précède en créant une application Ember/Node/Mongoose, car Ember préfère vraiment avoir un champ "id" avec lequel travailler.

77
Pascal Zajac
//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;
}

il existe une propriété "Schema.options.toObject.transform" pour effectuer l'inverse ou vous pouvez simplement configurer un identifiant virtuel.

23
user3087827

À partir de Mongoose v4.0, cette fonctionnalité est partiellement prise en charge prête à l'emploi. Il n'est plus nécessaire d'ajouter manuellement un champ virtuel id comme expliqué par @Pascal Zajac.

Mongoose assigne à chacun de vos schémas un identifiant virtuel getter par défaut qui retourne le contenu du document _id dans une chaîne, ou dans le cas de ObjectIds, son hexString. Si vous ne voulez pas que l'identifiant soit ajouté à votre schéma, vous pouvez le désactiver en passant cette option au schéma temps de construction. La source

Cependant, pour exporter ce champ vers JSON, il est toujours nécessaire de activer la sérialisation des champs virtuels:

Schema.set('toJSON', {
    virtuals: true
});
18
xaviert

Voici une version alternative de la réponse fournie par @ user3087827. Si vous trouvez que schema.options.toJSON est indéfini, vous pouvez utiliser:

schema.set('toJSON', {
     transform: function (doc, ret, options) {
         ret.id = ret._id;
         delete ret._id;
         delete ret.__v;
     }
}); 
18
Tom Makin

J'ai utilisé ceci:

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

Je pense que ce serait bien s'ils suppriment automatiquement _id lorsque les virtuals sont vrais.

8
Benamar

J'ai créé à cet effet un plugin facile à utiliser que je postule pour tous mes projets et pour tous les schémas du monde. Il convertit _id en id et supprime également le paramètre __v.

Donc, il convertit:

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

Pour un plus simple et plus propre:

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

Utilisation en tant que plugin global:

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

Ou pour un schéma spécifique:

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

J'espère que ça aide quelqu'un.

4
Adam Reis

Si vous utilisez lodash pour choisir les éléments de votre choix, cela fonctionnera pour vous.

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
Ivor Scott

Un autre pilote utilise cette option http://alexeypetrushin.github.com/mongo-lite set convertId sur true. Voir la section "Paramètres par défaut" pour plus de détails.

0
Alexey Petrushin

Vous pouvez également utiliser la fonction d'agrégation lorsque vous recherchez des éléments à renvoyer. $ project vous permettra de créer des champs que vous pourrez faire et l’affecter à _id.

<model>.aggregate([{$project: {_id: 0, id: '$_id'}], (err, res) => {
 // 
})
0
user2062241