一個簡單的數據增量更新策略(Android / MongoDB / Django)
我在做個人APP - CayKANJI - 的時候遇到一個問題:
如何增量式地把日語漢字數據地從server更新到APP端,即每次用戶運行更新操作時,僅僅獲取版本號高於本地緩存的內容。
數據格式
為了可以與mongoDB無縫結合,並省去編寫後臺代碼的麻煩,索性就把漢字數據保存成json文件,上傳到server後。交給web應用去讀取並寫入數據庫。
漢字文件就是普通的json格式。
{ "category": "行為ー2", "contents": [ { "kanji" : "尋", "on-yomi" : "ジン", "kun-yomi" : "たず-ねる", "examples": ["不明な點を尋ねる", "行方を尋ねて回る", "由來を尋ねる", "警官が怪しい男に尋問する", "尋常ではない行動"] }, { "kanji" : "促", "on-yomi" : "ソク", "kun-yomi" : "うなが-す", "examples": ["成長を促す", "発言を促す", "販売を促進する", "支払いを催促する"] } ] }
數據庫操作
然後利用不同的目錄做一個隊列,未被寫入數據庫的文件放在pending目錄。已經寫入的放在finished目錄。
這樣當webserver接收到第一次更新請求時,會檢測pengding目錄下是否有新的json文件,有的話就寫入到數據庫。並把json文件移動到finished目錄。
web端用的是Django
框架,使用pymongo
操作數據庫。
數據寫入
def write_to_db(self, path): with open(path) as my_file: self._db.kanji.insert(json.loads(my_file.read()))
def check_update(self): for (path, dirs, files) in os.walk(self.PENDING_DIR): for file in files: self.write_to_db(os.path.join(path, file)) # move sync-over file into ‘finished‘ directory shutil.move(os.path.join(path, file), os.path.join(self.FINISHED_DIR, file))
把json數據同步到數據庫後,就能夠在Android端發起請求來獲取數據。
可是。這樣做並不能在手機端實現增量更新,每次請求都會下載數據庫中全部的數據。事實上解決的方法也非常easy。給每條json數據加上一個版本號就搞定了。
增量數據的版本號控制
改動之前的json文件。加入一個version字段。
{ "category": "行為ー2", "version" : 0, "contents": [ { "kanji" : "尋", "on-yomi" : "ジン", "kun-yomi" : "たず-ねる", "examples": ["不明な點を尋ねる", "行方を尋ねて回る", "由來を尋ねる", "警官が怪しい男に尋問する", "尋常ではない行動"] }, { "kanji" : "促", "on-yomi" : "ソク", "kun-yomi" : "うなが-す", "examples": ["成長を促す", "発言を促す", "販売を促進する", "支払いを催促する"] } ] }
數據讀取
數據請求RESTfull
風格的url - http://www.liangfeizc.com/catykanji/download/0
download後面的數字表示這次請求的最低版本,server收到這個請求後會返回全部版本大於等於0的數據。
首先在url.py中加入url規則
url(r‘^download/(?P<version>\d+)$‘, ‘download_kanji‘),
然後在view.py中加入download_kanji
函數
def download_kanji(request, version=0): kanji = _mongo.get_kanji(int(version)) return HttpResponse(kanji, content_type="application/json")
讀取大於等於version的數據
def get_kanji(self, version): # check pending dir to see if there‘s any file self.check_update() result = self._db.kanji.find({"version": {"$gte": version}}) return json_util.dumps(result)
搞定了web端的增量更新規則。Android就沒什麽問題了。
Android端
Android的HTTP請求使用了AOSP的Volley
庫,僅僅要把uri拼接好,加入到Volley的RequestQueue就能夠了。
每次從server返回請求數據時,解析json文件後把最大的version的值加1後保存到Preference中。再次發送請求的時候直接從Preference中讀取這個版本號。拼接成一個請求指定版本號號的url就能夠了。
最後把解析完的json數據分成三個表保存到的數據庫就大公告成了。源代碼能夠看
https://github.com/LyndonChin
一個簡單的數據增量更新策略(Android / MongoDB / Django)