Neste artigo vamos ver um pouco dos sub-documentos utilizando MongooseJS.
Mongoose é uma biblioteca para node.js baseada em Schemas para modelar os dados de nossa aplicação. Tudo no Mongoose começa com um Schema, e cada schema mapeia uma collection no MongoBD e nessas collections.
O mongoDB é um banco de dados (open-source) não relacional e sua estrutura de dados é baseada em documentos no formato JSON.
Fazendo uma comparação com o SQL, um documento seria uma row. De modo análogo, um SUB-documento seria uma row ligada a outra row.
Sub Documentos
Digamos que seu sistema precisa de uma collection Usuario, e que cada usuário possua uma lista de serviços com seus devidos preços.
Exemplo:
{ name: "Eder Taveira", services: [ {name: "Eletricista", price: 10.00}, { name: "Marceneiro",price: 20.00 } ] }
Criando os Schemas com sub-docs no node (express):
[userModel.js]
var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/exemplo'); var serviceSchema = new Schema({ name: String }) var serviceUserSchema = new Schema({ //Mapeando su-doc service simples. service: {type: mongoose.Schema.Types.ObjectId, ref: 'services'}, price: Number }) var userSchema = new Schema({ name: String, //Mapeamento como array services: [serviceUserSchema] }) mongoose.model('services', serviceSchema); module.exports = mongoose.model('users', userSchema);
O Mongoose tem duas formas distintas de declarar um sub-documento, em formato de array (linha 12,[serviceUserSchema]) e em formato simples, chamando o Schema diretamente (linha 7).
Note que na linha 7, eu utilizo a seguinte sintaxe: {type: mongoose.Schema.Types.ObjectId, ref: ‘services’}. Com isso, estamos informando para o mongoose que queremos recuperar ali, o objeto service ligado pela primary key criada automaticamente pelo mondo (Exemplo: {“_id”: ObjectId(“54759eb3c090d83494e2d804”) } ).
Buscando, Atualizando e Removendo um Sub-documento
Vejamos um outro exemplo: Um usuário que pode favoritar/desfavoritar outros, similar às amizades das redes sociais.
*Explicações nos comentários do código.
[userModel.js]
var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/exemplo'); var Schema = mongoose.Schema; var favoritesSchema = new Schema({ userId : {type: mongoose.Schema.Types.ObjectId, ref: 'users'} }); var userSchema = new Schema({ email : { type: String, unique: true }, name : String, favorites : [favoritesSchema] });
[userController.js]
var userModel = require('../models/userModel.js'); module.exports = { favoriteToggle: function(req, res) { //Parâmetros recebidos via request var user = req.body.user; var favoriteId = req.body.favoriteId; userModel.findById({'_id': user._id}, function (err, user) { //Verifico se o ID do usuário a ser favoritado existe no sub-documento do usuário solicitante var fav = user.favorites.id(favoriteId); if (fav) { //Caso exista, eu o removo. fav.remove(); } else { //Caso não, o incluo. user.favorites.push({_id : favoriteId}); } //Salvo o documento com seus sub-documentos atualizados. user.save(function (err) { if (err) return handleError(err); return res.json(user); }); }); }
Outra forma de declarar sub-docs
var userSchema = new Schema({ favorite: [userId : {type: mongoose.Schema.Types.ObjectId, ref: 'users'}]}); //OU parentSchema = new Schema({ children: [new Schema(userId : {type: mongoose.Schema.Types
É isso ai pessoal!