我在使用MongoDB的NodeJS中開發演示應用程序,目前使用的模塊是Express和Mongoose。使用Mongoose從節點中插入,更新和從MongoDB中的複雜嵌入式集合中刪除
的主要思想是重拍一個PHP + MySQL app,其中MySQL數據庫包括三個表,在1:N關係:公司 - >現場>物品
的示例數據收集是這樣的:
[
{"id": 1,"name": "DemoCompanyOne", "fields":[
{"id": 1, "location": "DemoLocationOne", "items":[
{"_id": 1,"name": "DemoItemOne","price": 1500,"count": 16,"date": "2013-11-02 16:53:19"},
{"_id": 2,"name": "DemoItemTwo","price": 890,"count": 211,"date": "2013-11-02 16:53:19"}
]},
{"id": 2, "location": "DemoLocationTwo", "items":[
{"_id": 3,"name": "DemoItemThree","price": 9990,"count": 10,"date": "2013-11-02 19:12:40"},
{"_id": 4,"name": "DemoItemFour","price": 2500,"count": 20,"date": "2013-11-02 19:12:42"}
]}
]},
{"id": 2,"name": "DemoCompanyTwo", "fields":[
{"id": 3, "location": "DemoLocationThree", "items":[
{"_id": 5,"name": "DemoItemFive","price": 79000,"count": 11,"date": "2013-11-02 16:56:13"},
{"_id": 6,"name": "DemoItemSix","price": 649,"count": 8760,"date": "2013-11-02 16:56:13"},
{"_id": 7,"name": "DemoItemSeven","price": 149,"count": 4320,"date": "2013-11-02 16:57:19"}
]}
]}
]
我在貓鼬製作模式,如:
var Schema = mongoose.Schema, ObjectId = Schema.ObjectId
var Items = new Schema({
_id: ObjectId,
name: String,
price: Number,
count: Number,
date: { type: Date, default: Date.now }
});
var Field = new Schema({
id: Number,
location: String,
items: [Items]
});
var Company = new Schema({
id: Number,
name: String,
Fields: [Field]
});
var cmp = mongoose.model('company', Company, "company");
var flds = mongoose.model('fields', Field, "fields");
var itm = mongoose.model('items', Items, "items");
請注意,物品的_id在蒙戈改爲的ObjectId,因爲我希望這將幫助我HANDL e這些嵌入式收藏更好 - 它沒有。
我想插入項目到指定的位置,或增加選定項目的計數或刪除選定的項目。
的COMPANY_ID和FIELD_ID包含在URL,如:
app.post('/:company_id/:field_id', function(req, res) { ... })
這裏面的處理程序,我單獨的請求,如:
app.post('/:company_id/:field_id', function(req, res) {
var company = req.params.company_id;
var field = req.params.field_id;
if (req.body.new != null)
{
cmp.findOne({}).where('id').equals(company).where('fields.id').equals(field).exec(function(err, comps) {
if (comps == null)
{ res.render('error', {title: 'Error!', msg: 'No such field!'}); }
else
{
i=0;
while (i < comps.fields.length && comps.fields[i].id != field)
{ i++; }
var r = new itm({"_id": "", "name": req.body.name, "price":req.body.price, "count":req.body.count});
comps.fields[i].items.push(r);
comps.save();
}
});
}
else if (req.body.mod != null)
{
//...
}
else if (req.body.del != null)
{
//...
}
res.redirect('/'+company+'/'+field);
})
正如你看到的,在項目加入我是使用線性搜索找到領域,在那裏我可以推新制作的項目...這是非常非常醜陋的,我敢肯定,必須有很多簡單的方法來做到這一點...
而且,關於增量重刑或刪除?我不想以同樣的方式...
而且,對於第四個問題:您如何看待ID?如何實施它們?我應該在任何地方使用ObjectIds,或者在任何地方都不需要?
任何幫助和想法表示讚賞!
對於最近的答案感到抱歉:重新考慮和實施這個解決方案需要一些時間,但它工作正常,非常感謝你:放棄嵌入式文檔的想法應該是最後一個,但代碼很多**現在更簡單。 – Gardenee
沒問題,但也請注意,嵌入式文檔的檢索速度要快於與參考文檔連接的文檔。因此,有時您可能想要使用它們,例如爲用戶保留不同的聯繫方式(電子郵件,推特,臉書,物理地址等) – igorpavlov