• 一个简单的数据增量更新策略(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

  • 相关阅读:
    eclipse快捷键
    go 中 var声明对比
    Post 中 Body 的 ContentType 用 Postman 举例
    MongoDB随笔(二) mongorestore恢复数据库
    MongoDB随笔(零) mongod配置 ...不断完善...会变得很长很长很长……
    MongoDB随笔(一)mac OSX下brew安装MongoDB
    mac OSX的 brew软件包管理器 相当于 centos下的yum
    2021-01-27 解决mac使用brew update更新无反应的问题(切换git地址)
    Ruby中实现module继承
    redmine问题集锦
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7275105.html
Copyright © 2020-2023  润新知