zoukankan      html  css  js  c++  java
  • MongoDB(online) 优化

    MongoDB(online) 优化

    1. find、findOne

    • 项目实例
    MongoTemplate mongoTemplate = mongodbClient.getMongoTemplate();
    DBCollection cursor = mongoTemplate.getCollection("vip_batchsend_message");
    BasicDBObject query = new BasicDBObject();
    query.put("sms_code", sms_code);
    query.put("open_id", open_id);
    
    JSONObject message = new JSONObject();
    
    DBCursor cursor1 = cursor.find(query);
    LOGGER.info("-------------sms_code:" + sms_code + "----open_id:" + open_id + "--" + cursor1.size());
    if (cursor1.size() > 0) {
        DBObject dBObject = cursor1.next();
        String corp_code = dBObject.get("corp_code").toString();
        .....
    • 简单阐述
      1. 代码意图是如果记录存在就修改
      2. 只需要判断是否存在就完成目的
      3. find返回的是DBCursor,这里不合适,我们只需要知道是否存在即可
      4. 修改建议
        1. 固定的条件提前预先组合
        2. find改成findOne
        3. 判断只需要查询一条记录即可,用findOne就可以,直接获取一个Object,判断后即可根据Key获取Value进行后续操作
    • 建议修改
    BasicDBObject query = new BasicDBObject();
    query.put("sms_code", sms_code);
    query.put("open_id", open_id);
    MongoTemplate mongoTemplate = mongodbClient.getMongoTemplate();
    JSONObject message = new JSONObject();
    DBCollection cursor = mongoTemplate.getCollection("vip_batchsend_message");
    DBObject dbObject = cursor.findOne(query);
    if (dbObject.isPartialObject()) {
        LOGGER.info("-------------sms_code:" + sms_code + "----open_id:" + open_id + "--" + 1);
        String corp_code = dbObject.get("corp_code").toString();
        String vip_id = dbObject.get("vip_id").toString();
        Data data_corp_code = new Data("corp_code", corp_code, ValueType.PARAM);
        Data data_vip_id = new Data("vip_ids", vip_id, ValueType.PARAM);
        ......

    2. 操作 vip_emp_relation 的一个公共方法

    • 项目实例
     public DBCursor selectRelation(String app_user_name, String open_id) throws SQLException {
            MongoTemplate mongoTemplate = mongodbClient.getMongoTemplate();
            DBCollection cursor = mongoTemplate.getCollection(WxConst.table_vip_emp_relation);
    
            Map keyMap = new HashMap();
            keyMap.put("_id", app_user_name + open_id);
            BasicDBObject queryCondition = new BasicDBObject();
            queryCondition.putAll(keyMap);
            DBCursor dbCursor = cursor.find(queryCondition);
            return dbCursor;
        }
    • 简单阐述

      1. 查看此方法的引用,基本是做判断使用,没必要返回一个Cursor
      2. 如果引用的方法,有长任务,然后再操作,就会等待很长时间不释放资源
    • 建议修改

       public DBObject selectRelation(String app_user_name, String open_id) throws SQLException {
          Map keyMap = new HashMap();
          keyMap.put("_id", app_user_name + open_id);
          BasicDBObject queryCondition = new BasicDBObject();
          queryCondition.putAll(keyMap);
          MongoTemplate mongoTemplate = mongodbClient.getMongoTemplate();
          DBCollection cursor = mongoTemplate.getCollection(WxConst.table_vip_emp_relation);
          DBObject dbCursor = cursor.findOne(queryCondition);
          return dbCursor;
      }

    3. 查询记录数

    • 项目实例
    BasicDBObject basicDBObject=new BasicDBObject();
    basicDBObject.put("activity_code",activity_code);
    basicDBObject.put("open_id",open_id);
    basicDBObject.put("status","1");
    int count=cursor.find(basicDBObject).count();
    basicDBObject.put("sign_status","Y");
    int sign_count=cursor.find(basicDBObject).count();
    if(sign_count>0){
        result="您已签到成功,请勿重复签到";
    }else {
        if (count > 0) {
            BasicDBObject query=new BasicDBObject();
            query.put("activity_code",activity_code);
            query.put("open_id",open_id);
        ......
    • 简单阐述

      1. 根据条件获取记录数
      2. 没必要先获取文档游标再查询记录数
    • 建议修改

    BasicDBObject basicDBObject=new BasicDBObject(); basicDBObject.put("activity_code",activity_code);
    basicDBObject.put("open_id",open_id);
    basicDBObject.put("status","1");
    Long count=cursor.count(basicDBObject);
    basicDBObject.put("sign_status","Y");
    Long sign_count=cursor.count(basicDBObject);
    if(sign_count>0){
        result="您已签到成功,请勿重复签到";
    }else {
        if (count > 0) {
            BasicDBObject query=new BasicDBObject();
            query.put("activity_code",activity_code);
            query.put("open_id",open_id);
        ......

    4. save、insert

    • 项目实例
    if (cursor.find(basicDBObject).count() > 0){
        BasicDBObject basicDBObject1=new BasicDBObject();
        basicDBObject1.put("sign_status","Y");
        basicDBObject1.put("sign_date",Common.DATETIME_FORMAT.format(new Date()));
        BasicDBObject update=new BasicDBObject();
        update.put("$set",basicDBObject1);
        cursor.update(basicDBObj,update,true,false);
    }else {
        BasicDBObject dbObject = new BasicDBObject();
        dbObject.put("_id", app_id + "_" + activity_code  + "_" + open_id);
        dbObject.put("corp_code", corp_code);
        dbObject.put("sign_status","Y");
        dbObject.put("sign_date",Common.DATETIME_FORMAT.format(new Date()));
        dbObject.put("app_id", app_id);
        dbObject.put("activity_code", activity_code);
        dbObject.put("status", "0");
        dbObject.put("open_id", open_id);
        dbObject.put("vip", vip_array.getJSONObject(0));
        dbObject.put("modified_date", Common.DATETIME_FORMAT.format(new Date()));
        dbObject.put("created_date", Common.DATETIME_FORMAT.format(new Date()));
        cursor.save(dbObject);
    }
        ......
    • 简单阐述

      1. save 是先根据_id查询再修改,如果已经确认记录不存在可以省去查找的功能直接insert
    • 建议修改

    if (cursor.find(basicDBObject).count() > 0){
        BasicDBObject basicDBObject1=new BasicDBObject();
        basicDBObject1.put("sign_status","Y");
        basicDBObject1.put("sign_date",Common.DATETIME_FORMAT.format(new Date()));
        BasicDBObject update=new BasicDBObject();
        update.put("$set",basicDBObject1);
        cursor.update(basicDBObj,update,true,false);
    }else {
        BasicDBObject dbObject = new BasicDBObject();
        dbObject.put("_id", app_id + "_" + activity_code  + "_" + open_id);
        dbObject.put("corp_code", corp_code);
        dbObject.put("sign_status","Y");
        dbObject.put("sign_date",Common.DATETIME_FORMAT.format(new Date()));
        dbObject.put("app_id", app_id);
        dbObject.put("activity_code", activity_code);
        dbObject.put("status", "0");
        dbObject.put("open_id", open_id);
        dbObject.put("vip", vip_array.getJSONObject(0));
        dbObject.put("modified_date", Common.DATETIME_FORMAT.format(new Date()));
        dbObject.put("created_date", Common.DATETIME_FORMAT.format(new Date()));
        cursor.insert(dbObject);
    }
        ......

    5. 总结

    1. 以上是目前发现的问题及建议,会继续Review
    2. 涉及到IO的操作标配就是尽晚打开尽早释放
    3. 阿里的MongoDB默认没有启动读写分离(我已经测试确认过),我测试后会加上
    4. 业务实现过程,尽可能结构化数据,介绍拼接出错或Key不存在的异常
    5. 涉及到Cursor尽快手动关闭
    6. 其它项目也可以参考,或者抛出来
  • 相关阅读:
    函数式宏定义与普通函数
    linux之sort用法
    HDU 4390 Number Sequence 容斥原理
    HDU 4407 Sum 容斥原理
    HDU 4059 The Boss on Mars 容斥原理
    UVA12653 Buses
    UVA 12651 Triangles
    UVA 10892
    HDU 4292 Food
    HDU 4288 Coder
  • 原文地址:https://www.cnblogs.com/lzh-boy/p/9037053.html
Copyright © 2011-2022 走看看