暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

NoSQLBooster for MongoDB 中跨库关联查询原来这么简单

MongoDB学习园 2019-03-05
3035

使用 MongoDB 是我们常常会遇到一些特殊的需求需要跨库关联查询,比如订单明细缺商品重量需要补商品重量,而商品重量数据又在商品库中,这事就需要跨库关联操作,示例代码如下:

    // 使用 order 库,注意语句后面不要加分号
    use order


    var count = 0;
    db.order_detail.find({"store_code":"110"}).forEach(function(_order){
    // 在 goods 库查询 item 集合
    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 库来授权连接操作

        

            上面示例的代码,数量不多时还能勉强凑合着使用。当数据量达到上万条数据时就显示非常非常慢。因为更新一条数据需要单条 findOne 再单条 update。因此得优化,将单条查询改批量查询(缓存查询结果),示例代码如下:

      use order


      var count = 0;
      var items = {};
      db.getSiblingDB("goods").item.find(function(_item){
      // items 当做 map 使用, key 商品条码(barcode)
      items[_item.barcode] = _item;
      });
      db.order_detail.find({"store_code":"110"}).forEach(function(_order){
      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);
      }
      });
      print("更新条数:" + count);
      复制


      经过将单条查询改成批量查询后执行效率确实提升不少,但是还是觉得慢,还得继续优化,将单条更新改成批量更新,示例代码如下:

        use order


        var count = 0;
        var items = {};
        db.getSiblingDB("goods").item.find(function(_item){
        items[_item.barcode] = _item;
        });
        var ops = [];
        db.order_detail.find({"store_code":"110"}).forEach(function(_order){
        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 > 0 && count % 1000 == 0){
        // 批量更新, ordered:false 无序操作
        db.order_detail.bulkWrite(ops, {ordered:false});
        ops = [];
        print("更新条数:" + count);
        }
        });


        if(ops.length > 0){
        db.order_detail.bulkWrite(ops, {ordered:false});
        }
        print("更新完成,更新总条数:" + count);
        复制



        批量操作: 

        http://xuexiyuan.cn/article/detail/173.html


        最后修改时间:2019-12-24 11:24:43
        文章转载自MongoDB学习园,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论