2012-08-21 11 views
10

Ben Ekspres kullanıyorum ve (istek req.body.myObject yanar) nesnenin bu tür dönüştürmek için uygun bir yol arıyorum:Dizeye dayalı JSON'u Mongoose Schema nesnesi örneğine dönüştürmek için yerel bir özellik var mı?

var myObjectSchema = new Schema({ 
    name: String, 
    someNumber: Number, 
    someBoolean: Boolean 
}); 

: Bu şema örneği içine

{ 
    "name": "Foo", 
    "someNumber": "23", 
    "someBoolean": "on" 
} 

İlk nesnenin istekten geldiğine dikkat edin, bu nedenle tamamen Dizeler tarafından yapılmıştır.

Bunu başarmanın iyi bir yolu var mı? Değilse, bu özelliği bir aracı yazılım olarak nasıl uygulayacağınız konusunda bir öneriniz var mı?

+1

_ "İlk nesnenin istekten geldiğine dikkat edin, bu nedenle tamamen Dizeler tarafından yapılmıştır." _ - Neden uygun yerlere bir sayı ve bir boole döndürmek için onu değiştirmiyorsunuz? Aldığım cümlede "öylesine" kullanımınız sadece dizelere izin verildiğini ima eder, ancak JSON ise bu doğru değildir. (Yani, JSON kendisi dize tabanlı bir biçimdir, ancak _represent_ number ve booleans olabilir ve JSON ayrıştırıldığında bu özellikler sayı ve boole haline gelir ...) – nnnnnn

+0

Şemanızdaki özellikler sabit mi, yoksa ihtiyacınız mi? Dinamik mi? – Mahn

+0

@nnnnnn Sorun, Express'in 'myObject [name]: name, myObject [someNumber]: 23' biçimindeki bilgileri alması ve Express'in her özelliği varsayılan olarak bir String'e ayarlayarak myObject öğesini yapılandırmasıdır! – renatoargh

cevap

10

Bu konuya atıfta bulunarak Mongoose : Inserting JS object directly into db Evet, bunun için yerleşik bir özellik olduğunu anladım.

Sadece parametre olarak (formdan) yeni bir model geçen istek değerlerini oluşturmak:

function add(req, res){ 
    new Contact(req.body.contact).save(function(err){ 
     console.log("Item added"); 
     res.send(); 
    }); 
}; 

Bu sizin için otomatik malzeme dönüştürür!

+1

Temasın önünde "yeni" olması gerekmez. Bu düğümde pahalı. function add (req, res) { İletişim (req.body.contact) .save (işlev (err) { console.log ("Öğe eklendi"); res.send(); }); }; – fino

+0

Merhaba @fino, tavsiyeniz için teşekkür ederiz! “Yeni” nin düğüm için pahalı olmasıyla ilgili herhangi bir kaynak sağlayabilir misiniz? Yeni başlayan biri olarak henüz duymadım! Teşekkürler – renatoargh

+0

birçok neden burada eric bazı iyi olanları var http://ericleads.com/2012/09/stop-using-constructor-functions-in-javascript/. nodejs olanlar için nodejs bellek yönetimi ve yığın boyutu için arama yapın. – fino

0

şema statik şartıyla bir teorik tembel olmayan sofistike bir yol gidebiliriz ve sadece nesnenin kendisini geçen değerlerini yerine hardcode: Muhtemelen aradığınız değil cevabını

var someObject = { 
    name: "Foo", 
    someNumber: "23", 
    someBoolean: "on" 
} 

var myObjectSchema = new Schema({ 
    name: someObject.name, 
    someNumber: parseInt(someObject.someNumber, 10), 
    someBoolean: (someObject.someBoolean == "on") 
}); 

ama Daha iyi bir şey yoksa, düşünecek bir şey olabilir.

+1

Tahmin edeceğiniz gibi, yeni bir Şema yazdığım her defasında yeniden yazmak zorunda kalmadan, genel olarak bunu yapmak için bir yol arıyorum. – renatoargh

2

Bu cevabın zaten kabul edildiğini biliyorum, ancak mongoose'un çoğu döküm işini sizin için yaptığını belirtmek istedim. Mongoose'un bunu yapması uygun olsa da, mongo'nun gerçek davranışını soyutlar.

PersonCollection.find({_id: "4cdf00000000000000007822"}, ...); 

Bunun nedeni ise: bu olur eser değil (firavun faresi olmadan) doğrudan veritabanını sorgulamak çalışırsa, ancak

PersonModel.findById("4cdf00000000000000007822", ...); 

: Örneğin, firavunfaresi böyle bir şey yapalım ObjectIds dizeleri değil, nesnelerdir. Dahili olarak, firavun faresi bir objectId için bu dizeyi dönüştürür ve sonra nihai sorgu böyle tür görünüyor böylece veritabanında bir sorgu gerçekleştirir:

PersonCollection.find({_id: ObjectId("4cdf00000000000000007822")}, ...); 

Ayrıca, şemasındaki her yolu "pudra" yöntemi vardır. Bu özel bir yöntem, ama ihtiyacın olduğunda çok kullanışlı. caster AŞAĞIDAKİ BELİRTİLEN YÖNTEMLERİN BELİRLENMEMİŞ VE UYARI OLMADAN DEĞİŞTİRİLMESİNİ LÜTFEN UNUTMAYIN. (Bağırıyor için üzgün) KENDİ RİSK AT KULLANIMI:

// Use PersonModel.schema.paths() to get all paths and loop over them if you want 
var key = "name"; 
var pathObj = PersonModel.schema.path(key); 
if(!pathObj) pathObj = PersonModel.schema.virtualpath(key); 
if(!pathObj) { /* not found: return, continue, exit, whatever */ } 

// UNDOCUMENTED: USE AT YOUR OWN RISK 
var caster = pathObj.caster || pathObj; 
var castedValue = caster.cast(req.body.name); 

bunu biliyorum Neden? Çünkü, mongo'nun toplanma gibi daha gelişmiş özelliklerinden bazılarını kullanmak isterseniz, boru hattını oluştururken kendi değerlerinizi kullanmanız gerekir. Ayrıca, $in operatörünü kullanan belirli sorgular için değerleri manuel olarak çevirmem gerekiyordu ... belki de buna artık gerek yok. Puan, beklediğiniz sonuçları almakta sorun yaşıyorsanız, değerleri kendiniz almayı deneyin.

+0

Araştırmadan sonra bunu üretimde kullanmak için aklınızdan çıkmış olabilirsiniz. Olmadı! –

+1

Ünite testleri ile değil ... İnsanlar belgesiz özelliklerini sık sık kullanırlar ve eğer kodunuzu test ederseniz,% 100 güvende olursunuz. Eğer metot ortadan kalkarsa, testiniz üretime gitmeden çok önce ortaya çıkarır ve onarırsınız. Ayrıca kendi riskinizle kullanmak konusunda uyarıyorum. Test yapmazsanız, bu sizin sorununuz ve aldığınız risktir;) –

İlgili konular