2012-08-21 25 views
10

Tôi đang sử dụng Express và tôi đang tìm kiếm một cách thuận tiện để chuyển đổi loại đối tượng (mà đi kèm theo yêu cầu req.body.myObject):Có một tính năng riêng để chuyển đổi chuỗi dựa trên JSON thành cá thể đối tượng Mongoose Schema không?

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

Into một thể hiện của Schema này:

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

Lưu ý rằng đối tượng đầu tiên xuất phát từ yêu cầu, do đó nó được tạo ra hoàn toàn bằng Strings.

Có cách nào tốt đẹp để đạt được điều này không? Nếu không, bạn sẽ có bất kỳ đề xuất về cách thực hiện tính năng này như là một middleware?

+1

_ "Chú ý rằng đối tượng đầu tiên xuất phát từ yêu cầu, do đó nó được tạo thành hoàn toàn bằng chuỗi." _ - Tại sao bạn không thay đổi nó để trả về một số và boolean ở những vị trí thích hợp? Việc bạn sử dụng "như vậy" trong câu tôi trích dẫn ngụ ý chỉ có chuỗi được phép, nhưng điều đó không đúng nếu đó là JSON. (Tức là, JSON chính nó là một định dạng dựa trên chuỗi, nhưng nó có thể _represent_ số và booleans, và khi JSON được phân tích cú pháp các thuộc tính như vậy trở thành số và booleans ...) – nnnnnn

+0

Các thuộc tính trong lược đồ của bạn có cố định hay không họ năng động? – Mahn

+0

@nnnnnn Vâng, vấn đề là Express lấy thông tin từ biểu mẫu 'myObject [name]: name, myObject [someNumber]: 23', và Express tự xây dựng myObject theo mặc định thiết lập mọi thuộc tính thành một String! – renatoargh

Trả lời

10

Bằng cách tham chiếu đến chủ đề này Mongoose : Inserting JS object directly into db Tôi đã tìm ra rằng có, có tính năng tích hợp sẵn cho việc này.

Bạn chỉ cần xây dựng một giá trị yêu cầu mô hình qua mới (từ mẫu) như các thông số:

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

Nó tự động chuyển đổi những thứ dành cho bạn!

+1

bạn không cần phải có một "mới" ở phía trước của Liên hệ. Đó là tốn kém trong nút. chức năng thêm (req, res) { Liên hệ (req.body.contact) .save (function (err) { console.log ("Item added"); res.send(); }); }; – fino

+0

Xin chào @fino, cảm ơn lời khuyên của bạn! Bạn có thể cung cấp bất kỳ tài nguyên nào về 'new' đắt tiền cho nút không? Là một người mới bắt đầu, tôi chưa nghe về nó! Cảm ơn – renatoargh

+0

nhiều lý do eric có một số lý do tại đây http://ericleads.com/2012/09/stop-using-constructor-functions-in-javascript/. cho các nodejs, tìm kiếm quản lý bộ nhớ nodejs và kích thước heap. – fino

0

Cung cấp schema là tĩnh, một lý thuyết có thể đi theo con đường lười biếng, không phức tạp và chỉ hardcode các giá trị thay vì đi qua các đối tượng chính 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") 
}); 

Có thể không phải là câu trả lời bạn đang tìm kiếm, nhưng có thể là một cái gì đó để xem xét nếu không có gì tốt hơn có sẵn.

+1

Như bạn nghĩ, tôi đang tìm kiếm một cách để làm điều đó một cách tổng quát, mà không phải viết lại nó mỗi khi tôi viết một lược đồ mới. – renatoargh

2

Tôi biết câu trả lời này đã được chấp nhận, nhưng tôi muốn chỉ ra rằng mongoose chăm sóc hầu hết việc truyền cho bạn ... phần lớn thời gian. Mặc dù nó rất tiện lợi, nhưng nó trừu tượng hóa hành vi thực sự của mongo. Ví dụ, cầy mangut cho phép bạn làm điều gì đó như thế này:

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

Tuy nhiên, nếu bạn đã cố gắng để truy vấn cơ sở dữ liệu trực tiếp (không có cầy mangut), điều này sẽ không công việc:

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

Điều này là do ObjectIds không phải là chuỗi ... chúng là đối tượng. Bên trong, cầy mangut chuyển đổi mà chuỗi đến một ObjectId và sau đó thực hiện một truy vấn đối với cơ sở dữ liệu để truy vấn cuối cùng trông kinda như thế này:

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

Ngoài ra, mỗi con đường trong một sơ đồ có một phương pháp "caster". Đây là một phương pháp riêng tư, nhưng nó darn tiện dụng khi bạn cần nó. XIN LƯU Ý R THENG caster PHƯƠNG PHÁP MÔ TẢ DƯỚI DƯỚI DƯỚI ĐÂY VÀ CÓ THỂ THAY ĐỔI KHÔNG CẢNH BÁO. SỬ DỤNG RỦI RO RIÊNG CỦA BẠN (xin lỗi vì đã la hét):

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

Tại sao tôi biết điều này? Bởi vì nếu bạn muốn sử dụng một số tính năng nâng cao hơn của mongo như tập hợp, bạn sẽ cần phải đúc các giá trị của riêng bạn khi bạn xây dựng đường dẫn. Tôi cũng cần phải tự đúc các giá trị cho các truy vấn nhất định sử dụng toán tử $in ... có thể điều này không cần thiết nữa. Điểm là, nếu bạn gặp khó khăn khi nhận kết quả mong đợi, hãy thử tự mình đúc các giá trị.

+0

Bạn sẽ hết tâm trí để sử dụng điều này trong sản xuất sau khi nghiên cứu. Yikes! –

+1

Không phải với các bài kiểm tra đơn vị ... Mọi người sử dụng các tính năng không có giấy tờ thường xuyên và nếu bạn kiểm tra mã của mình, bạn an toàn 100%. Nếu phương pháp này biến mất, kiểm tra của bạn sẽ tiết lộ nó trước khi bạn đi vào sản xuất và bạn sửa nó. Tôi cũng cảnh báo về việc sử dụng có nguy cơ của riêng bạn. Nếu bạn không viết các bài kiểm tra, đó là vấn đề của bạn và đó là rủi ro bạn thực hiện;) –

Các vấn đề liên quan