天天看點

NoSQLBooster for MongoDB 中跨庫關聯查詢

使用 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);