Node.js, Express ve MongoDB ile mongoose kullanarak CRUD tarzı bir REST hizmeti yapıyorum. Bu servis, halihazırda mevcut bir android uygulamasının kullanıcılarının bireysel veritabanlarının içeriğini çevrimiçi olarak yüklemesine/senkronize etmesine izin verecektir.ObjectID referansları için mongoose içinde UUID'leri kullanma
Zaten varolan uygulama için veri modeli, daha kısa, monoton MongoDB stili _id
alanlarıyla çakışan UUID'leri (Java'da oluşturulan) kullanır. Veri modeli zaten mevcut olduğundan ve birçok kullanıcıdan gelen verilerle doldurulduğundan, kaynak verileri monotonik MongoDB tarzı _id
s'ye dönüştüremiyorum. Bu benim düşünebildiğim 2 seçenek ile beni terk etti: 1) Mongo/Mongoose (veya başka bir ODM) monotonik _id
s yerine tam UUID'lerle güzelce oynayın veya 2) ek olarak mongoose modeline bir uuid alanı ekleyin _id
alanına ve bu yaklaşımın tuzakları ile mücadele. # 1 numaralı seçeneği seçmeyi ve ObjectID referansları ile ilgili sorunları çalıştırmayı deniyorum.
Orijinal olarak mongoose-uuid numaralı telefondan tökezledim, ancak maalesef bu benim kullanım durumumda düzgün çalışmıyor çünkü yeni Mongoose nesneleri oluştururken açıkça ayarlanmış _id
değerinin üzerine yazılıyordu. Eklenti kodunun içine dalmak, bir nesnenin yeni olduğunu varsayar (Mongoose'un .isNew
değerini kontrol ederek) ve böylece _id
'u yeni bir uuid ile üzerine yazar. Mongo'da yeni belgeler oluştururken orijinal uuid'i korumam gerektiğinden, bu eklenti benim için çalışmıyor.
Sonraki, benzer bir konuda mongoose'un yaratıcısı Aaron Heckmann tarafından post buldum. Bu yardımcı oldu, ancak şu anda teknik olarak onlar String `_ids kullanarak birbirlerini referans olarak görüyoruz, çünkü ben şimdi bir kez, benim SHIDMOZ şemalarım referans olarak ObjectID tarafından başvurmadığım bir problemle karşılaşıyorum.
Şema örneği:
var mongoose = require('mongoose');
var uuid = require('node-uuid');
var Schema = mongoose.Schema;
var trackPassSchema = new Schema({
_id: { type: String, default: function genUUID() {
uuid.v1()
}},
//Omitting other fields in snippet for simplicity
vehicle: [
{type: Schema.Types.ObjectId, required: true, ref: 'Vehicle'}
]
});
module.exports = mongoose.model('TrackPass', trackPassSchema);
Referans şema: Ben olsun
var trackPass = new TrackPass(req.body);
//Force the ID to match what was put into the request
trackPass._id = req.params.id;
trackPass.save(function (err) { ... }
: benim uygulamadan geçirilen edilmiş bir trackPass save()
çağırmak girişiminde
var mongoose = require('mongoose');
var uuid = require('node-uuid');
var Schema = mongoose.Schema;
var vehicleSchema = new Schema({
_id: { type: String, default: function genUUID() {
uuid.v1()
}},
//Omitting other fields in snippet for simplicity
description: {type: String},
year: {type: Number}
});
module.exports = mongoose.model('Vehicle', vehicleSchema);
aşağıdaki hata:
{ [CastError: Cast to ObjectId failed for value "b205ac4d-fd96-4b1e-892a-d4fab818ea2a" at path "vehicle"]
message: 'Cast to ObjectId failed for value "b205ac4d-fd96-4b1e-892a-d4fab818ea2a" at path "vehicle"',
name: 'CastError',
type: 'ObjectId',
value: ["b205ac4d-fd96-4b1e-892a-d4fab818ea2a"],
path: 'vehicle' }
Tipik Mongo ObjectID'lerden daha uzun olan Dizeleri kullandığım için bu hatanın anlamlı olduğunu düşünüyorum. ObjectID başvurusu olmadan, diğer koleksiyonlardan başvurulan nesneleri populate()
alabileceğime inanmıyorum. Şema tanımlarımdaki diğer iç içe geçmiş nesnelere atıfta bulunamayacağımı düşünürsem de, bu yaklaşımı beğenmedim, çünkü ODM'yi kullanmanın yararlarından birçoğunu kaybedeceğim. Başka düşünceler var mı?
: Adam yorumlarda belirttiği gibi
, Size
default
değerini basitleştirmek olabilir:Yani senin
trackPassSchema
değiştirmek gerekir : {type: String, default: uuid.v1} ' –@AdamC Öneriniz, oluşturulan uuid'in bu nesnenin ömrü boyunca sabit olmasını sağlar. –
Hayır, bu iyi. 'default: uuid.v1()' bu soruna sahip olurdu, ancak varsayılan değil: uuid.v1'. – JohnnyHK