2011-08-12 45 views
30

Estoy usando mangosta (nodo), ¿cuál es la mejor manera de generar id en lugar de _id?MongoDB: salida 'id' en lugar de '_id'

+1

Para lectores nuevos: a continuación verá varios enfoques * diferentes *. Es aconsejable leerlos todos antes de elegir, en lugar de ir ciegamente por la mayoría de los votos o aceptados. ¡Aclamaciones! – sshow

Respuesta

18

Creo un método toClient() en mis modelos donde hago esto. Es también un buen lugar para renombrar/eliminar otros atributos que no desea enviar al cliente:

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

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

    return obj; 
}); 
+0

Realmente nuevo para la mangosta, esto parece lo que quiero. ¿cómo se llama esto al cliente? Normalmente hago, find(), y recupero un objeto de docs, luego simplemente res.send (docs). Entonces, en este caso, ¿llamo a res.write (docs [1] .toClient()) en cada documento? gracias – Johnny

+0

esto no parece funcionar para mí ahora - ¿ha cambiado el método de hacer esto en Mongoose? – outside2344

+3

virtuals es probablemente lo que quieres. – Leonidas

59

Dado que está utilizando Mongoose, puede usar 'virtuales', que son esencialmente campos falsos que crea Mongoose. No están almacenados en la base de datos, que sólo son rellenados en tiempo de ejecución:

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

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

Cualquier toJSON tiempo se llama en el modelo creado a partir de este esquema, se incluirá un campo 'id' que coincide con _ID campo que Mongo genera. Del mismo modo, puede establecer el comportamiento de toObject de la misma manera.

Ver:

Puede abstracta esto en un baseschema todos sus modelos a continuación, extender/invocar para mantener la lógica en un solo lugar. Escribí lo anterior al crear una aplicación Ember/Node/Mongoose, ya que Ember realmente prefiere tener un campo 'id' para trabajar.

+1

+1 funcionó bien para mí –

+3

Muy buena solución (+1). También agregaría 'Schema.set ('toObject', {virtuals: true})' para poder ver los virtuales en salida al usar 'console.log (obj)'. – Tom

+2

Esto mantiene el campo _id. Prefiero la solución de transformación en cambio, la proporcionada por shakinfree funcionó para mí. –

19
//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; 
} 

hay una propiedad "Schema.options.toObject.transform" hacer lo contrario o se puede acaba de configurar como un identificador de virtual.

+0

¡Gracias por esto! –

15

Aquí hay una versión alternativa de la respuesta proporcionada por @ user3087827. Si usted encuentra que schema.options.toJSON no está definido, puede utilizar:

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

A partir de la mangosta v4.0 parte de esta funcionalidad es apoyado fuera de la caja. Ya no es necesario agregar manualmente un campo virtual id como se explica en @Pascal Zajac.

Mangosta asigna a cada uno de los esquemas de un id captador virtual por defecto que devuelve el campo de documentos _ID fundido en una cadena, o en el caso de ObjectID, su HexString. Si no desea que se agregue un identificador de identificador al su esquema, puede deshabilitarlo pasando esta opción en el esquema tiempo de construcción.Source

Sin embargo, a exportación este campo para JSON, sigue siendo necesario para permiten serialización de campos virtuales:

Schema.set('toJSON', { 
    virtuals: true 
}); 
+3

Esto era cierto mucho antes que v4.0, pero lo que OP quiere es que * just * id (y no _id) sea devuelto. Solo le digo a mangosta que incluya la identificación virtual que devuelve ambos. – neverfox

3

creé una herramienta fácil de usar plugin para este propósito que Solicito todos mis proyectos y todos los esquemas a nivel mundial. Convierte _id en id y elimina el parámetro __v también.

Por lo tanto, se convierte:

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

Para un limpiador simple y:

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

uso como un plugin mundial:

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

O para un esquema específico:

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

Espero que esto ayude a alguien.

4

He utilizado este:

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

Creo que sería genial si se suprimen automáticamente cuando _id virtuals es cierto.

0

También puede utilizar la función de agregado al buscar elementos para devolver. $ project le permitirá crear campos, lo que puede hacer y asignarlo a _id.

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