使用 MongoDB 是我們常常會遇到一些特殊的需求需要跨庫關聯查詢,比如訂單明細缺商品重量需要補商品重量,而商品重量資料又在商品庫中,這事就需要跨庫關聯操作,示例代碼如下:
// 使用 order 庫,注意語句後面不要加分号
use order
var count = ;
db.order_detail.find({"store_code":"110"}).forEach(function(_order){
var item = db.getSiblingDB("goods").item.findOne({"barcode":_order.barcode});
if(item){
db.order_detail.update({_id:_order._id},{$set:{"weight":item.weight}},false,true);
count++;
}else{
print("商品不存在, 條碼:" + _order.barcode);
}
});
print("更新條數:" + count);
注意:跨庫查詢時必須使用 admin 庫來授權連接配接。
上面示例的代碼,數量不多時還能勉強湊合着使用。當資料量達到上萬條資料時就顯示非常非常慢。因為更新一條
QQ賬号資料需要單條 findOne 在單條 update。是以得優化,将單條查詢改批量查詢(緩存查詢結果),示例代碼如下:
var items = {};
db.getSiblingDB("item").goods.find({"store_code":"110"}).forEach(function(_item){
items[_item.barcode] = _item;
});
var item = items[_order.barcode];
if(item){
db.order_detail.update({_id:_order._id},{$set:{"weight":item.weight}},false,true);
count++;
}else{
print("商品不存在, 條碼:" + _order.barcode);
}
進過将單條查詢改成批量查詢後執行效率确實提升不少,但是還是覺得慢,還得繼續優化,将單條更新改成批量更新,示例代碼如下:
db.getSiblingDB("item").goods({"store_code":"110"}).forEach(function(_item){
items[_item.barcode] = _item;
var ops = [];
var item = items[_order.barcode];
if(item){
var f = {_id:_order._id};
var upd = {$set:{"weight":item.weight}};
ops.push({"updateMany":{"filter":f, "update":upd, "upsert":false}});
count++;
}else{
print("商品不存在, 條碼:" + _order.barcode);
}
if(count > && count % 1000 == ){
// 批量更新, ordered:false 無序操作
db.order_detail.bulkWrite(ops, {ordered:false});
ops = [];
print("更新條數:" + count);
}
if(ops.length > ){
db.order_detail.bulkWrite(ops, {ordered:false});
}
print("更新完成,更新總條數:" + count);