Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Mongoose

olá, eu tenho as seguintes Collections:

1:

var hourmeterDeviceSchema = mongoose.Schema({

    name: {type: String, required: true},
    description: {type: String, required: true},
    group: {type: schema.Types.ObjectId, ref: 'DeviceGroup', required:true},  
    device: {type: schema.Types.ObjectId, ref: 'Device', required:true},  
    inputs: [{
        number: {type: Number, required: true},    
        description: {type: String, required: true},
        time: {type: Number, required: true}
    }]
},
{ collection: 'hourmeterDevices' });

mongoose.model('HourmeterDevice', hourmeterDeviceSchema);

2:

 var mongoose = require('mongoose');
 var schema = mongoose.Schema;

var hourmeterAlarmSchema = mongoose.Schema({

    name: {type: String, required: true},
    description: {type: String, required: true},
    device: {type: schema.Types.ObjectId, ref:'HourmeterDevice', required:true},
    input: {type: schema.Types.ObjectId, ref: '', required:true},  
},
{ collection: 'hourmeterAlarms' });

mongoose.model('HourmeterAlarm', hourmeterAlarmSchema);

Na primeira, eu consigo referenciar 'group' e 'device' porque são collections separadas, como faço para referenciar um 'input' do array 'inputs' na segunda collection ?

4 respostas

Oi Felipe! Tudo bem?

Olha, primeiramente há uma coisa a ser pensada em todo esse modelo. Quando você quer trabalhar com relacionamentos, o MongoDB começa a ser o banco menos indicado.

É claro que podemos criar relacionamentos, mas se você começa a ter muitos, sua aplicação não terá uma boa performance. O banco que é excelente em relacionamentos é o relacional. Nos joins, ele é imbatível e os pseudo joins do MongoDB criados pelo Mongoose (um quebra galho) deixam a desejar.

Bancos NoSQL como MongoDB não substituem bancos relacionais e são usados mais para guardar documentos sem relacionamentos.

Tenho visto muitos alunos usando a MEAN Stack mas sem se aperceber dessa questão que coloquei. Talvez seja interessante você ver algum banco SQL para trabalhar na sua Stack. MongoDB é usado para gravar logs e informações autocontidas, como os dados de um post etc.

Bom, agora vamos voltar ao seu problema. É possível realizar um ao relacionamento, é isso que você quer? Se for, é o mesmo processo que você fez antes, mais vai referenciar o próprio esquema.

É essa a sua dúvida?

Olá, mais ou menos.

Sim, eu achei que a aplicação poderia ser não relacional, mas comecei a me deparar em situações que eu precisava cadastrar um objeto, e precisava usar um select (no html) para preencher um campo.

Não é viável trocar o banco agora, talvez em uma futura versão do sistema, porém no desenvolvimento não notei perda de desempenho, pode ser porque a aplicação possui apenas umas 10 collections e não tenho muitos dados cadastrados.

Para resolver o problema eu tentei referenciar o 'input' mas nao funcionou, ocorre este erro:

schema hasn't been registered for model "HourmeterDevice.inputs".

input: {type: schema.Types.ObjectId, ref:'HourmeterDevice.inputs', required:true},

Eu poderia criar um array de alarmes dentro do dispositivo, dessa forma ficaria no mesmo schema, mas mesmo assim não sei como colocar no campo 'input' do alarme um input do array 'inputs' do dispositivo.

Entendo. Então, sobre o seu problema. Você só consegue fazer um relacionamento artificial no lado da aplicação com ref apontado para outro esquema e não para a propriedade de outro esquema.

// Não rola
input: {type: schema.Types.ObjectId, ref:'HourmeterDevice.inputs', required:true},
// Em teoria, já rola.
input: {type: schema.Types.ObjectId, ref:'HourmeterDevice', required:true},

Ainda sobre a MEAN Stack. Infelizmente ela popularizou o uso indiscriminado do MongoDB. MongoDB é rápido justamente por não ter que realizar JOINS em relacionamentos de composição, na qual o documento filho não existe sem o documento pai. O banco é totalmente desnormalizado para ganhar performance. Para relações de agregação, o banco SQL é imbatível e o MongoDB apanha de lavada, apanha mesmo!. Ele não foi projetado para fazer JOIN, aliás, ele nem é capaz de fazer isso, como eu esclareci, quem faz o join é sua aplicação e não o banco com o auxílio do Mongoose.

Por fim, não é raro se trabalhar com os dois bancos, um SQL e outro NoSQL na mesma aplicação, usando cada banco para um cenário específico. Se o seu cliente quiser realizar algum estudo no seu banco não poderá usar ferramentas conceituadas do mercado, pois o MongoDB não é compatível com a maioria delas.

Não quero complicar sua vida, longe disso, mas seu esquema do banco me fez compartilhar essas informações.

solução!

Oi Felipe, pescou a ideia do relacionamento? Se estiver tudo certinho, me dá um feedback aqui.

Sucesso e bom estudo, meu aluno.