MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Защо Mongoose има както схеми, така и модели?

РЕДАКТИРАНЕ: Въпреки че това е било полезно за много хора, както е споменато в коментарите, то отговаря на „как“, а не на защо. За щастие, защо на въпроса е отговорено и другаде, с този отговор на друг въпрос. Това е свързано в коментарите от известно време, но осъзнавам, че мнозина може да не стигнат толкова далеч, когато четат.

Често най-лесният начин да отговорите на този тип въпроси е с пример. В случая някой вече го е направил вместо мен :)

Разгледайте тук:

http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/

РЕДАКТИРАНЕ: Оригиналната публикация (както е споменато в коментарите) изглежда вече не съществува, така че я възпроизвеждам по-долу. Ако някога се върне или току-що се е преместило, моля, уведомете ме.

Той дава прилично описание на използването на схеми в моделите в mongoose и защо бихте искали да го направите, а също така ви показва как да избутвате задачи чрез модела, докато схемата е свързана изцяло със структурата и т.н.

Оригинална публикация:

Нека започнем с прост пример за вграждане на схема в модел.

var TaskSchema = new Schema({
    name: String,
    priority: Number
});
 
TaskSchema.virtual('nameandpriority')
    .get( function () {
        return this.name + '(' + this.priority + ')';
    });
 
TaskSchema.method('isHighPriority', function() {
    if(this.priority === 1) {
        return true;
    } else {
        return false;
    }
}); 
 
var ListSchema = new Schema({
    name: String,
    tasks: [TaskSchema]
});
 
mongoose.model('List', ListSchema);
 
var List = mongoose.model('List');
 
var sampleList = new List({name:'Sample List'});

Създадох нова TaskSchema обект с основна информация, която задачата може да има. Виртуален атрибут Mongoose е настроен за удобно комбиниране на името и приоритета на задачата. Тук посочих само getter, но виртуалните сетери също се поддържат.

Дефинирах и прост метод за задача, наречен isHighPriority за да демонстрирате как методите работят с тази настройка.

В ListSchema дефиниция, ще забележите как tasks ключът е конфигуриран да държи масив от TaskSchema обекти. task key ще стане екземпляр на DocumentArray която предоставя специални методи за работа с вградени документи на Mongo.

Засега предадох само ListSchema обект в mongoose.model и напусна TaskSchema навън. Технически не е необходимо да обръщате TaskSchema в официален модел, тъй като няма да го запазваме в собствената му колекция. По-късно ще ви покажа как не вреди на нищо, ако го направите, и може да ви помогне да организирате всичките си модели по същия начин, особено когато започнат да обхващат множество файлове.

С List настройка на модела нека добавим няколко задачи към него и да ги запишем в Mongo.

var List = mongoose.model('List');
var sampleList = new List({name:'Sample List'});
 
sampleList.tasks.push(
    {name:'task one', priority:1}, 
    {name:'task two', priority:5}
);
 
sampleList.save(function(err) {
    if (err) {
        console.log('error adding new list');
        console.log(err);
    } else {
        console.log('new list successfully saved'); 
    }
});

Атрибутът tasks в екземпляра на нашия List модел (sampleList ) работи като обикновен масив на JavaScript и можем да добавяме нови задачи към него с помощта на push. Важното, което трябва да забележите, са tasks се добавят като обикновени JavaScript обекти. Това е фино разграничение, което може да не е веднага интуитивно.

Можете да проверите от обвивката на Mongo, че новият списък и задачи са запазени в mongo.

db.lists.find()
{ "tasks" : [
    {
        "_id" : ObjectId("4dd1cbeed77909f507000002"),
        "priority" : 1,
        "name" : "task one"
    },
    {
        "_id" : ObjectId("4dd1cbeed77909f507000003"),
        "priority" : 5,
        "name" : "task two"
    }
], "_id" : ObjectId("4dd1cbeed77909f507000001"), "name" : "Sample List" }

Сега можем да използваме ObjectId за да изтеглите Sample List и повторете през неговите задачи.

List.findById('4dd1cbeed77909f507000001', function(err, list) {
    console.log(list.name + ' retrieved');
    list.tasks.forEach(function(task, index, array) {
        console.log(task.name);
        console.log(task.nameandpriority);
        console.log(task.isHighPriority());
    });
});

Ако изпълните последния бит код, ще получите грешка, че вграденият документ няма метод isHighPriority . В текущата версия на Mongoose не можете директно да получите достъп до методи на вградени схеми. Има отворен билет за коригиране и след като зададе въпроса на Mongoose Google Group, manimal45 публикува полезно решение, което да се използва засега.

List.findById('4dd1cbeed77909f507000001', function(err, list) {
    console.log(list.name + ' retrieved');
    list.tasks.forEach(function(task, index, array) {
        console.log(task.name);
        console.log(task.nameandpriority);
        console.log(task._schema.methods.isHighPriority.apply(task));
    });
});

Ако стартирате този код, трябва да видите следния изход в командния ред.

Sample List retrieved
task one
task one (1)
true
task two
task two (5)
false

Имайки предвид това заобикаляне, нека обърнем TaskSchema в модел мангуста.

mongoose.model('Task', TaskSchema);
 
var Task = mongoose.model('Task');
 
var ListSchema = new Schema({
    name: String,
    tasks: [Task.schema]
});
 
mongoose.model('List', ListSchema);
 
var List = mongoose.model('List');

TaskSchema определението е същото като преди, така че го пропуснах. След като се превърне в модел, ние все още можем да получим достъп до основния обект на схемата, използвайки нотация с точки.

Нека създадем нов списък и да вградим два екземпляра на Task модел в него.

var demoList = new List({name:'Demo List'});
 
var taskThree = new Task({name:'task three', priority:10});
var taskFour = new Task({name:'task four', priority:11});
 
demoList.tasks.push(taskThree.toObject(), taskFour.toObject());
 
demoList.save(function(err) {
    if (err) {
        console.log('error adding new list');
        console.log(err);
    } else {
        console.log('new list successfully saved'); 
    }
});

Докато вграждаме екземплярите на модела Task в списъка, ние извикваме toObject върху тях, за да конвертирате данните си в обикновени JavaScript обекти, които List.tasks DocumentArray очаква. Когато запазите екземпляри на модела по този начин, вашите вградени документи ще съдържат ObjectIds .

Пълният пример за код е достъпен като същност. Надяваме се, че тези решения ще помогнат за изглаждане на нещата, тъй като Mongoose продължава да се развива. Все още съм доста нов за Mongoose и MongoDB, така че не се колебайте да споделяте по-добри решения и съвети в коментарите. Приятно моделиране на данни!



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Вложен масив за попълване на мангуста

  2. Как да защитите вашите бази данни с отворен код с ClusterControl

  3. Как мога да използвам променлива с регулярни изрази в заявка за MongoDB

  4. Променете типа на полето в агрегирането на mongoDB и използва ли $lookup индекс върху полета или не?

  5. Как да се свържа с mongodb с node.js (и удостоверявам автентичността си)?