2014-12-12 5 views
11

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ı?

cevap

14

populate()'u _id ObjectID dışındaki türlerin değerleriyle kullanabilirsiniz, ancak aynı tanımlamayı referans tanımında kullanmanız gerekir.`_ID: Bu biraz basitleştirmek olabilir

var trackPassSchema = new Schema({ 
    _id: { type: String, default: uuid.v1 }, 
    vehicle: [ 
     {type: String, required: true, ref: 'Vehicle'} 
    ] 
}); 
+6

: Adam yorumlarda belirttiği gibi

var trackPassSchema = new Schema({ _id: { type: String, default: function genUUID() { uuid.v1() }}, vehicle: [ {type: String, required: true, ref: 'Vehicle'} ] }); 

, Size default değerini basitleştirmek olabilir:

Yani senin trackPassSchema değiştirmek gerekir : {type: String, default: uuid.v1} ' –

+0

@AdamC Öneriniz, oluşturulan uuid'in bu nesnenin ömrü boyunca sabit olmasını sağlar. –

+2

Hayır, bu iyi. 'default: uuid.v1()' bu soruna sahip olurdu, ancak varsayılan değil: uuid.v1'. – JohnnyHK