Desenvolvimento

21 nov, 2017

Sub-documentos com o super mongoose, node e express

Publicidade

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!

Referências: