標籤:created int 查詢 condition ids line isp convert obj
MongoDB(online) 最佳化
- 1. find、findOne
- 2. 操作 vip_emp_relation 的一個公用方法
- 3. 查詢記錄數
- 4. save、insert
- 5. 總結
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(); .....
- 簡單闡述
- 代碼意圖是如果記錄存在就修改
- 只需要判斷是否存在就完成目的
- find返回的是DBCursor,這裡不合適,我們只需要知道是否存在即可
- 修改建議
- 固定的條件提前預先組合
- find改成findOne
- 判斷只需要查詢一條記錄即可,用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; }
簡單闡述
- 查看此方法的引用,基本是做判斷使用,沒必要返回一個Cursor
- 如果引用的方法,有長任務,然後再操作,就會等待很長時間不釋放資源
建議修改
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); ......
簡單闡述
- 根據條件擷取記錄數
- 沒必要先擷取文檔遊標再查詢記錄數
建議修改
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);} ......
簡單闡述
- 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. 總結
- 以上是目前發現的問題及建議,會繼續Review
- 涉及到IO的操作標配就是盡晚開啟儘早釋放
- 阿里的MongoDB預設沒有啟動讀寫分離(我已經測試確認過),我測試後會加上
- 業務實現過程,儘可能結構化資料,介紹拼接出錯或Key不存在的異常
- 涉及到Cursor儘快手動關閉
- 其它項目也可以參考,或者拋出來
MongoDB(online) 最佳化