¿Cómo crear un esquema de Mongoose con una matriz de ID de objeto?

82

He definido un esquema de usuario de mangosta:

var userSchema = mongoose.Schema({
  email: { type: String, required: true, unique: true},
  password: { type: String, required: true},
  name: {
      first: { type: String, required: true, trim: true},
      last: { type: String, required: true, trim: true}
  },
  phone: Number,
  lists: [listSchema],
  friends: [mongoose.Types.ObjectId],
  accessToken: { type: String } // Used for Remember Me
});

var listSchema = new mongoose.Schema({
    name: String,
    description: String,
    contents: [contentSchema],
    created: {type: Date, default:Date.now}
});
var contentSchema = new mongoose.Schema({
    name: String,
    quantity: String,
    complete: Boolean
});

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

el parámetro de amigos se define como una matriz de ID de objeto. En otras palabras, un usuario tendrá una matriz que contiene los ID de otros usuarios. No estoy seguro de si esta es la notación adecuada para hacer esto.

Estoy tratando de enviar un nuevo amigo a la matriz de amigos del usuario actual:

user = req.user;
  console.log("adding friend to db");
  models.User.findOne({'email': req.params.email}, '_id', function(err, newFriend){
    models.User.findOne({'_id': user._id}, function(err, user){
      if (err) { return next(err); }
      user.friends.push(newFriend);
    });
  });

sin embargo, esto me da el siguiente error:

TypeError: Object 531975a04179b4200064daf0 no tiene método 'cast'

usuario2481095
fuente

Respuestas:

130

Si desea utilizar la función de llenado de Mongoose, debe hacer lo siguiente:

var userSchema = mongoose.Schema({
  email: { type: String, required: true, unique: true},
  password: { type: String, required: true},
  name: {
      first: { type: String, required: true, trim: true},
      last: { type: String, required: true, trim: true}
  },
  phone: Number,
  lists: [listSchema],
  friends: [{ type : ObjectId, ref: 'User' }],
  accessToken: { type: String } // Used for Remember Me
});
exports.User = mongoose.model('User', userSchema);

De esta forma puedes hacer esta consulta:

var User = schemas.User;
User
 .find()
 .populate('friends')
 .exec(...)

Verá que cada usuario tendrá una serie de usuarios (los amigos de este usuario).

Y la forma correcta de insertar es como dijo Gabor:

user.friends.push(newFriend._id);
Rodrigo Reis
fuente
1
Pero luego crea una matriz que parece en [{"$oid": "dfdfsdfsg565ls"},...]lugar de["hkugh87tgkgk", ....]
CodyBugstein
2
Así es como se supone que debe ser, una lista de ObjectIds. Mangosta ya los maneja.
Rodrigo Reis
¿Qué hace populate()exactamente?
Kenny Worden
@KennyWorden el método populate de mongoose simula una unión en bases de datos relacionales tradicionales. Entonces, en este caso, el relleno reemplazará la matriz de amigos con una matriz de documentos de Usuarios.
Rodrigo Reis
Hola, @RodrigoReis, ¿puedes decirme cómo escribir una consulta si quiero` nombre -> primero = 'ajay'; `Estoy escribiendo esto aproximadamente, pero no obtengo ningún resultado.
Ajay Gupta
22

Yo mismo soy nuevo en Mongoose, así que no estoy del todo seguro de que esto sea correcto. Sin embargo, parece que ha escrito:

friends: [mongoose.Types.ObjectId],

Creo que la propiedad que está buscando se encuentra aquí:

friends: [mongoose.Schema.Types.ObjectId],

Sin embargo, es posible que los documentos hayan cambiado desde que publicó esta pregunta. Disculpas si ese es el caso. Consulte los documentos de Mongoose SchemaTypes para obtener más información y ejemplos.

curzmg
fuente
8

Intentaría esto.

user.friends.push(newFriend._id);

o

friends: [userSchema],

pero no estoy seguro de si esto es correcto.

Gabor Laser Raz
fuente