2011-11-13 76 views
44

Usando node.js, mongodb en mongoHQ y mangosta. Estoy configurando un esquema para Categorías. Me gustaría usar el documento ObjectId como mi categoryId.Cómo establecer ObjectId como un tipo de datos en mongoose

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 
var Schema_Category = new Schema({ 
    categoryId : ObjectId, 
    title  : String, 
    sortIndex : String 
}); 

entonces corro

var Category = mongoose.model('Schema_Category'); 
var category = new Category(); 
category.title = "Bicycles"; 
category.sortIndex = "3"; 

category.save(function(err) { 
    if (err) { throw err; } 
    console.log('saved'); 
    mongoose.disconnect();  
}); 

en cuenta que yo no proporcionan un valor para categoryId. Supuse que Mangosta usará el esquema para generarlo, pero el documento tiene el "_id" usual y no "categoryId". ¿Qué estoy haciendo mal?

Respuesta

95

A diferencia de los RBDM tradicionales, mongoDB no le permite definir ningún campo aleatorio como clave principal, el campo _id DEBE existir para todos los documentos estándar.

Por esta razón, no tiene sentido crear un campo uuid separado.

En mangosta, el tipo ObjectId no se usa para crear un nuevo uuid, sino que se usa principalmente para hacer referencia a otros documentos.

Aquí se muestra un ejemplo:

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 
var Schema_Product = new Schema({ 
    categoryId : ObjectId, // a product references a category _id with type ObjectId 
    title  : String, 
    price  : Number 
}); 

Como se puede ver, no tendría mucho sentido para poblar categoryId con un OBJECTID.

Sin embargo, si desea un campo uuid muy bien nombrado, mongoose proporciona propiedades virtuales que le permiten representar (referenciar) un campo.

Compruébelo usted mismo:

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 
var Schema_Category = new Schema({ 
    title  : String, 
    sortIndex : String 
}); 

Schema_Category.virtual('categoryId').get(function() { 
    return this._id; 
}); 

Así que ahora, cada vez que llame category.categoryId, mangosta sólo devuelve _ID lugar.

También puede crear un método de "ajuste" para que pueda establecer las propiedades virtuales, echa un vistazo a this link para obtener más información

+0

¡Respuesta perfecta! Gracias! – idophir

+0

Después de establecer una propiedad virtual, probé: db.cats.find ({categoryId: ObjectId ("the id")}} pero obtuve resultados nulos. cuando uso db.cats.find ({_ id: ObjectId ("the id")}) Recibí un doc. Por lo tanto, parece que la propiedad virtual no se puede usar para buscar. Creo que podría ser más fácil administrar el código si fuera posible hacer referencia a cada ID con un nombre claro, en lugar de usar _id para todo. Solo un pensamiento ... – idophir

12

que estaba buscando una respuesta diferente para el título de la pregunta, así que tal vez otras personas será también.

Para establecer el tipo como un OBJECTID (lo que puede hacer referencia a author como el autor de book, por ejemplo), es posible hacer como:

const Book = mongoose.model('Book', { 
    author: { 
    type: mongoose.Schema.Types.ObjectId, // here you set the author ID 
              // from the Author colection, 
              // so you can reference it 
    required: true 
    }, 
    title: { 
    type: String, 
    required: true 
    } 
}); 
+0

gracias por esto – Maverick

0

Mi solución sobre el uso de OBJECTID

// usermodel.js 

const mongoose = require('mongoose') 
const Schema = mongoose.Schema 
const ObjectId = Schema.Types.ObjectId 


let UserSchema = new Schema({ 
    username: { 
    type: String 
    }, 
    events: [{ 
    type: ObjectId, 
    ref: 'Event' // Reference to some EventSchema 
    }] 
}) 

UserSchema.set('autoIndex', true) 

module.exports = mongoose.model('User', UserSchema) 

Usando el método populate de la mangosta

// controller.js 

const mongoose = require('mongoose') 
const User = require('./usermodel.js') 

let query = User.findOne({ name: "Person" }) 

query.exec((err, user) => { 
    if (err) { 
    console.log(err) 
    } 

    user.events = events 
    // user.events is now an array of events 
}) 
0

La solución provista por @dex funcionó para mí. Pero quiero agregar algo más que también funcionó para mí: Use

let UserSchema = new Schema({ 
    username: { 
    type: String 
    }, 
    events: [{ 
    type: ObjectId, 
    ref: 'Event' // Reference to some EventSchema 
    }] 
}) 

si lo que desea crear es una referencia de matriz.Pero si lo que quiere es una referencia de objeto, que es lo que creo que podría estar buscando todos modos, quitar los soportes de la hélice valor, como este:

let UserSchema = new Schema({ 
    username: { 
    type: String 
    }, 
    events: { 
    type: ObjectId, 
    ref: 'Event' // Reference to some EventSchema 
    } 
}) 

mirada a los 2 fragmentos bien. En el segundo caso, el valor prop de los eventos clave no tiene corchetes sobre la definición del objeto.

Cuestiones relacionadas