İki tür nesne birbirine o kadar yakın görünür ki, her ikisine de sahip olmak gereksizdir. Hem şemalara hem de modellere sahip olmanın amacı nedir ?
İki tür nesne birbirine o kadar yakın görünür ki, her ikisine de sahip olmak gereksizdir. Hem şemalara hem de modellere sahip olmanın amacı nedir ?
Yanıtlar:
Genellikle bu tür soruları yanıtlamanın en kolay yolu bir örnek vermektir. Bu durumda, birisi zaten benim için yaptı :)
Buraya bir göz atın:
http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/
DÜZENLEME: Orijinal gönderi (yorumlarda belirtildiği gibi) artık mevcut değil, bu yüzden onu aşağıda yeniden oluşturuyorum. Geri dönerse veya yeni taşınırsa lütfen bana bildirin.
Firavun faresindeki modellerde şemaları kullanmanın ve bunu neden yapmak isteyeceğinizin iyi bir tanımını verir ve ayrıca şema tamamen yapı vb. İle ilgili iken model aracılığıyla görevleri nasıl iteceğinizi gösterir.
Orijinal Gönderi:
Bir modelin içine bir şema yerleştirmenin basit bir örneğiyle başlayalım.
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
Bir görevin sahip olabileceği temel bilgileri içeren yeni bir nesne oluşturdum . Bir Mongoose sanal özniteliği , Görevin adını ve önceliğini uygun şekilde birleştirmek için ayarlanır. Burada sadece bir alıcı belirledim ancak sanal ayarlayıcılar da destekleniyor.
isHighPriority
Yöntemlerin bu kurulumla nasıl çalıştığını göstermek için adında basit bir görev yöntemi de tanımladım .
Gelen ListSchema
tanım size görevler anahtar bir dizi tutmak için nasıl yapılandırıldığını fark edeceksiniz TaskSchema
nesneler. Görev anahtarı, DocumentArray
gömülü Mongo belgeleriyle uğraşmak için özel yöntemler sağlayan bir örnek haline gelecektir .
Şimdilik ListSchema
nesneyi sadece mongoose.model'e ilettim ve TaskSchema'yı dışarıda bıraktım. Teknik olarak TaskSchema
resmi bir modele dönüştürmeye gerek yok çünkü onu kendi koleksiyonumuza kaydetmeyeceğiz. Daha sonra, yaparsanız hiçbir şeye zarar vermeyeceğini size göstereceğim ve tüm modellerinizi özellikle birden fazla dosyayı yaymaya başladıklarında aynı şekilde düzenlemenize yardımcı olabilir.
İle List
modeli kurulumu en ona bir çift görevler ekleyebilir ve bunlara tasarruf Mongo için izin verin.
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');
}
});
List
Modelimizin ( simpleList
) örneğindeki görevler özniteliği normal bir JavaScript dizisi gibi çalışır ve push kullanarak ona yeni görevler ekleyebiliriz. Dikkat edilmesi gereken önemli şey, görevlerin normal JavaScript nesneleri olarak eklenmesidir. Bu, hemen sezgisel olmayabilecek ince bir ayrımdır.
Mongo kabuğundan yeni listenin ve görevlerin mongo'ya kaydedildiğini doğrulayabilirsiniz.
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" }
Şimdi , görevlerini ObjectId
yukarı çekmek Sample List
ve yinelemek için kullanabiliriz .
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());
});
});
Son kod parçasını çalıştırırsanız, gömülü belgenin bir yöntemi olmadığını söyleyen bir hata alırsınız isHighPriority
. Mongoose'un mevcut sürümünde, gömülü şemalardaki yöntemlere doğrudan erişemezsiniz. Bunu düzeltmek için açık bir bilet var ve soruyu Mongoose Google Grubu'na sorduktan sonra, manimal45 şimdilik kullanmak için yararlı bir çözüm yayınladı.
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));
});
});
Bu kodu çalıştırırsanız, komut satırında aşağıdaki çıktıyı görmelisiniz.
Sample List retrieved
task one
task one (1)
true
task two
task two (5)
false
Aklımızdaki bu geçici TaskSchema
çözümle , onu bir Mongoose modeline çevirelim.
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
Tanım Ben bunu sol yüzden önce aynıdır. Bir modele dönüştürüldüğünde, temelde yatan Şema nesnesine nokta gösterimini kullanarak hala erişebiliriz.
Yeni bir liste oluşturalım ve içine iki Görev modeli örneği yerleştirelim.
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');
}
});
Görev modeli örneklerini Listeye yerleştirirken, toObject
verilerini List.tasks
DocumentArray
bekledikleri düz JavaScript nesnelerine dönüştürmelerini istiyoruz . Model örneklerini bu şekilde kaydettiğinizde, gömülü belgeleriniz içerecektir ObjectIds
.
Kod örneğinin tamamı bir özet olarak mevcuttur . Umarım bu geçici çözümler, Mongoose gelişmeye devam ederken işleri yumuşatmaya yardımcı olur. Mongoose ve MongoDB'de hala oldukça yeniyim, bu yüzden lütfen yorumlarda daha iyi çözümler ve ipuçları paylaşmaktan çekinmeyin. Mutlu veri modelleme!
Şema , MongoDB koleksiyonunuzda saklanacak tüm belgelerin yapısını tanımlayan bir nesnedir; tüm veri öğeleriniz için türler ve doğrulayıcılar tanımlamanıza olanak tanır.
Model , adlandırılmış bir koleksiyona kolay erişim sağlayan, koleksiyonu sorgulamanıza ve bu koleksiyona kaydettiğiniz tüm belgeleri doğrulamak için Şemayı kullanmanıza olanak tanıyan bir nesnedir. Şema, Bağlantı ve koleksiyon adı birleştirilerek oluşturulur.
Orijinal olarak Valeri Karpov, MongoDB Blog tarafından ifade edilmiştir.
Kabul edilen cevabın aslında sorulan soruyu cevapladığını sanmıyorum. Cevap, Mongoose'un neden bir geliştiricinin hem bir Şema hem de bir Model değişkeni sağlamasını zorunlu kıldığını açıklamıyor . Geliştiriciye olan ihtiyacı ortadan kaldırdıkları bir çerçeve örneğiveri şemasını tanımlamak için django vardır - geliştirici, modellerini models.py dosyasına yazar ve şemayı yönetmek için çerçeveye bırakır. Django ile olan deneyimlerime göre, bunu neden yaptıklarının ilk akla gelen nedeni kullanım kolaylığıdır. Belki daha da önemlisi KURU (kendinizi tekrar etmeyin) prensibidir - modeli değiştirdiğinizde şemayı güncellemeyi hatırlamanıza gerek yoktur - django bunu sizin için yapar! Rails ayrıca sizin için verilerin şemasını da yönetir - bir geliştirici şemayı doğrudan düzenlemez, ancak şemayı işleyen geçişleri tanımlayarak değiştirir.
Mongoose'un şemayı ve modeli ayıracağını anlamamın bir nedeni, iki şemadan bir model oluşturmak isteyeceğiniz örneklerdir. Böyle bir senaryo, yönetmeye değer olandan daha fazla karmaşıklık getirebilir - bir model tarafından yönetilen iki şemanız varsa, bunlar neden tek bir şema değil?
Belki de asıl soru, geleneksel ilişkisel veritabanı sisteminin kalıntısıdır. NoSQL / Mongo dünyasında, belki şema MySQL / PostgreSQL'den biraz daha esnektir ve bu nedenle şemayı değiştirmek daha yaygın bir uygulamadır.
Nedenini anlamak için? Mongoose'un gerçekte ne olduğunu anlamak zorundasın?
Mongoose, MongoDB ve Node JS için bir nesne veri modelleme kitaplığıdır ve daha yüksek düzeyde bir soyutlama sağlar. Yani bu biraz Express ve Node arasındaki ilişkiye benziyor, bu yüzden Express normal Node üzerinde bir soyutlama katmanı iken Mongoose, normal MongoDB sürücüsüne göre bir soyutlama katmanıdır.
Bir nesne veri modelleme kitaplığı, daha sonra bir veritabanıyla etkileşime girecek Javascript kodu yazmamızın bir yoludur. Yani veritabanımıza erişmek için normal bir MongoDB sürücüsü kullanabilirdik, bu gayet iyi çalışırdı.
Ancak bunun yerine Mongoose kullanıyoruz çünkü kutudan çıktığı haliyle bize uygulamalarımızın daha hızlı ve daha basit geliştirilmesine olanak tanıyan çok daha fazla işlevsellik sağlıyor.
Bu nedenle, Mongoose'un bazı özellikleri bize verilerimizi ve ilişkimizi modellemek için şemalar, kolay veri doğrulama, basit bir sorgu API'si, ara katman yazılımı ve çok daha fazlasını sunar.
Mongoose'da bir şema, verilerimizi modellediğimiz, verilerin yapısını, varsayılan değerleri ve doğrulamayı tanımladığımız, ardından bu şemayı alıp ondan bir model oluşturduğumuz, bir model temelde şema etrafında bir sarmalayıcıdır. bu, belgeleri oluşturmak, silmek, güncellemek ve okumak için veritabanıyla fiilen arayüz oluşturmamızı sağlar.
Şemadan bir model oluşturalım.
const tourSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'A tour must have a name'],
unique: true,
},
rating: {
type: Number,
default: 4.5,
},
price: {
type: Number,
required: [true, 'A tour must have a price'],
},
});
//tour model
const Tour = mongoose.model('Tour', tourSchema);
Anlaşmaya göre bir model adının ilk harfi büyük yazılmalıdır.
Firavun faresi ve şema kullanarak oluşturduğumuz modelimizin bir örneğini oluşturalım. ayrıca, veritabanımızla etkileşimde bulunun.
const testTour = new Tour({ // instance of our model
name: 'The Forest Hiker',
rating: 4.7,
price: 497,
});
// saving testTour document into database
testTour
.save()
.then((doc) => {
console.log(doc);
})
.catch((err) => {
console.log(err);
});
Yani hem schama hem de modle firavun faresine sahip olmak hayatımızı kolaylaştırıyor.