sql >> Databáze >  >> NoSQL >> MongoDB

Proč má Mongoose jak schémata, tak modely?

UPRAVIT: Ačkoli to bylo užitečné pro mnoho lidí, jak je uvedeno v komentářích, odpovídá to spíše „jak“ než proč. Naštěstí, proč byla otázka zodpovězena i jinde, touto odpovědí na jinou otázku. Toto bylo v komentářích již nějakou dobu odkazováno, ale uvědomuji si, že mnozí se při čtení nemusí dostat tak daleko.

Často je nejjednodušší odpovědět na tento typ otázek pomocí příkladu. V tomto případě to za mě už někdo udělal :)

Podívejte se sem:

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

UPRAVIT: Zdá se, že původní příspěvek (jak je zmíněn v komentářích) již neexistuje, proto jej reprodukuji níže. Pokud by se někdy vrátila nebo se právě přesunula, dejte mi prosím vědět.

Poskytuje slušný popis použití schémat v modelech v mongoose a proč byste to chtěli udělat, a také vám ukazuje, jak předávat úkoly prostřednictvím modelu, zatímco schéma je o struktuře atd.

Původní příspěvek:

Začněme jednoduchým příkladem vložení schématu do modelu.

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'});

Vytvořil jsem nové TaskSchema objekt se základními informacemi, které úkol může mít. Virtuální atribut Mongoose je nastaven tak, aby pohodlně kombinoval název a prioritu úkolu. Specifikoval jsem pouze getter zde, ale virtuální settery jsou také podporovány.

Také jsem definoval jednoduchou metodu úlohy nazvanou isHighPriority demonstrovat, jak metody fungují s tímto nastavením.

V ListSchema definice si všimnete, jak tasks klíč je nakonfigurován tak, aby obsahoval pole TaskSchema objektů. task key se stane instancí DocumentArray který poskytuje speciální metody pro práci s vloženými dokumenty Mongo.

Prozatím jsem prošel pouze ListSchema objekt do mongoose.model a opustili TaskSchema ven. Technicky není nutné zapínat TaskSchema do formálního modelu, protože jej nebudeme ukládat do jeho vlastní sbírky. Později vám ukážu, že pokud to uděláte, ničemu neublíží a že vám to pomůže uspořádat všechny vaše modely stejným způsobem, zvláště když začnou zahrnovat více souborů.

Pomocí List nastavení modelu, přidejte k němu několik úkolů a uložte je do 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'); 
    }
});

Atribut úkolů v instanci našeho List model (sampleList ) funguje jako běžné pole JavaScriptu a můžeme do něj přidávat nové úkoly pomocí push. Důležitá věc, které je třeba si povšimnout, jsou tasks jsou přidány jako běžné objekty JavaScriptu. Je to jemný rozdíl, který nemusí být hned intuitivní.

Z prostředí Mongo můžete ověřit, že nový seznam a úkoly byly uloženy do 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" }

Nyní můžeme použít ObjectId vytáhněte Sample List a procházet jeho úkoly.

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());
    });
});

Pokud spustíte poslední část kódu, zobrazí se chyba, že vložený dokument nemá metodu isHighPriority . V aktuální verzi Mongoose nemáte přímý přístup k metodám na vložených schématech. Existuje otevřený lístek, jak to opravit, a poté, co položil otázku skupině Mongoose Google, manimal45 zveřejnil užitečné řešení, které lze prozatím použít.

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));
    });
});

Pokud tento kód spustíte, měli byste na příkazovém řádku vidět následující výstup.

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

S ohledem na toto řešení pojďme změnit TaskSchema do modelu Mongoose.

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 definice je stejná jako předtím, takže jsem ji vynechal. Jakmile se změní na model, stále máme přístup k základnímu objektu Schema pomocí tečkové notace.

Vytvořme nový seznam a vložíme do něj dvě instance modelu 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'); 
    }
});

Když vkládáme instance modelu úloh do seznamu, voláme toObject na nich převést jejich data na prosté objekty JavaScript, které List.tasks DocumentArray očekává. Když uložíte instance modelu tímto způsobem, budou vaše vložené dokumenty obsahovat ObjectIds .

Kompletní příklad kódu je k dispozici jako podstata. Doufejme, že tato řešení pomohou věci usnadnit, protože se Mongoose nadále vyvíjí. V Mongoose a MongoDB jsem stále docela nový, takže neváhejte a podělte se o lepší řešení a tipy v komentářích. Šťastné modelování dat!



  1. Uložte relaci uživatele v Redis s ASP.NET Core v Azure

  2. Rozsah dotazu pro stránkování MongoDB

  3. Jak se MongoDb instaluje pomocí Meteoru?

  4. Vizualizace topologie vašeho clusteru v ClusterControl