Python3.7+Django2.0.4配合Mongodb打造高性能高扩展标签云存储方案
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_141
书接上回,之前有一篇文章提到了标签云系统的构建:Python3.7+jieba(结巴分词)配合Wordcloud2.js来构造网站标签云(关键词集合),但是这篇只是浅显的说明了一下如何进行切词以及前端如何使用wordcloud2.js进行前端展示,本次主要讨论下标签分词切出来之后,如何进行存储。
假设我们目前文章-标签体系的需求是这样:
每篇文章都具有唯一的标题、描述以及 URL。
每篇文章都具有一个或多个标签。
每篇文章都具有作者的名称,以及喜欢
每篇文章都有用户的评论,用户名、消息、日期时间以及评论的喜欢度。
每篇文章都可以有 0 个或多个评论。
那么如果使用关系型数据库来设计,比较简单的设计方案可以是这样:
可以注意到,标签和文章的对应关系还是简单的一对多,如果做成比较灵活的多对多还需要增加一张关系表,这样就是四张表了。
如果使用nosql比如Mongodb来说,只需要一张表(聚合)就可以实现:
{
   _id: POST_ID
   title: TITLE_OF_POST,
   description: POST_DESCRIPTION,
   by: POST_BY,
   url: URL_OF_POST,
   tags: [TAG1, TAG2, TAG3],
   likes: TOTAL_LIKES,
   comments: [
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
         like: LIKES
      },
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
         like: LIKES
      }
   ]
}
可以看到标签是由数组实现的,那么关系型数据库mysql和非关系型数据库mongodb在标签实现中本质上有什么区别呢?
关系数据库如mysql中标签云的实现是简单的,标签和文章分别在不同的表中,通过join可以比较简单的查询出标签的统计数据。 而MongoDB为快速水平扩张以及极高的性能而优化,在MongoDB中没有join,倾向于使用embedding来代替linking关系。
假设我们的需求又有了变化,普通博客变身成为具有数百万篇文章的小说站.每个小说都有许多布尔属性,大约一万个可能的属性,每篇小说都有十几个章节,假设我希望能够实时(几毫秒)请求给出的前n项任何属性组合的标签。
你会选择推荐什么解决方案?毫无疑问,如果你在寻找极具扩展性的方案,Mongodb无疑更好。
而且从业务角度上来讲,无论是通过标签查文章,还是文章查标签这样的需求,都非常灵活,当然了根据文章查标签一般没问题,一般都是根据标签查文章的时候有性能问题,如果是纯关系数据库比如mysql很难解决性能问题,所以要借助 es 索引解决。es 索引的时候可以将 tagid 用逗号分隔,可以很快的根据一个 tagid,或者多个 tagid 查询到关联的文章 id,一般文章列表都是分页的,有这些文章 id 了,再去关系数据库里面取文章就行了,但是es又是另外一件事了,回头我们再讨论。
随后使用Django2.0.4来实现,首先安装好python的mongodb操作库pymongo
pip3 install pymongo
值得一提的是,它会有一个相对应bson模块 也就是说 PyMongo模块的实现是基于和它一起的bson模块的。
bson是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型;BSON有三个特点:轻量性、可遍历性、高效性,但是空间利用率不是很理想。
基于Django插入标签的视图:
import pymongo
from bson import json_util as jsonb
mongo_client = pymongo.MongoClient(host='localhost', port=27017)
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
from django.views import View  
class InsertTagsHandler(View):  
    def get(self,request):
        db = mongo_client.test12
        table = db.test12
        res = table.find({"title":'123'}).count()
        print(res)  
        if res > 0:
            result = '重复数据'
            return HttpResponse(json.dumps({'result':result},ensure_ascii=False))
        else:
            table.insert({'title':'123','desc':['123','123']})
            return HttpResponse(json.dumps({'result':'添加成功'},ensure_ascii=False))
基于django通过文章查询标签
class FindArticleHandler(View):  
    def get(self,request):
        db = mongo_client.test12
        table = db.test12  
        res = table.find_one({"title":'123'},{"desc":1})  
        return HttpResponse(jsonb.dumps(res,ensure_ascii=False))
基于django分组查询获取所有标签以及标签出现次数的统计
class TagsStatHandler(View):  
    def get(self,request):
        db = mongo_client.test12
        table = db.test12  
        pipeline = [{'$unwind':"$tags"},{'$group': {'_id': "$tags", 'count': {'$sum': 1}}},]
        res = table.aggregate(pipeline)  
        return HttpResponse(jsonb.dumps(res,ensure_ascii=False))
基于django通过标签反查文章
class Tags2ArticleHandler(View):  
    def get(self,request):
        db = mongo_client.test12
        table = db.test12  
        res = table.find({"tags":{'$in':["123"]}})  
        return HttpResponse(jsonb.dumps(res,ensure_ascii=False))
结语:经此一役,Mongodb的特点跃然纸上:结构灵活,表结构更改相对自由,不用每次alter的时候付出代价,适合业务快速迭代,而且json原生和大多数的语言有天然的契合。还支持数组,嵌套文档等数据类型。
原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_141
Python3.7+Django2.0.4配合Mongodb打造高性能高扩展标签云存储方案的更多相关文章
- Python3.7+jieba(结巴分词)配合Wordcloud2.js来构造网站标签云(关键词集合)
		
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_138 其实很早以前就想搞一套完备的标签云架构了,迫于没有时间(其实就是懒),一直就没有弄出来完整的代码,说到底标签对于网站来说还是 ...
 - 使用Python3.7+Django2.0.4配合vue.js2.0的组件递归来实现无限级分类(递归层级结构)
		
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_133 所谓的无限极分类是啥?其实简单点说就是一个人类可以繁衍出多个后代,然后一个后代又可以分另外多个后代这样无限繁衍下去(可以想象 ...
 - python3.5+django2.0快速入门(二)
		
昨天写了python3.5+django2.0快速入门(一)今天将讲解配置数据库,创建模型,还有admin的后台管理. 配置数据库 我们打开mysite/mysite/settings.py这个文件. ...
 - python3.5+django2.0快速入门(一)
		
因为这篇教程需要用到anaconda的一些操作,如果还不懂anaconda的操作的同学可以看下这篇文章python 入门学习之anaconda篇. 创建python3+的开发环境 直接在终端输入:co ...
 - Django2.0+小程序技术打造微信小程序助手✍✍✍
		
Django2.0+小程序技术打造微信小程序助手 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题 ...
 - Python3.6+Django2.0以上 xadmin站点的配置和使用
		
1. xadmin的介绍 django自带的admin站点虽然功能强大,但是界面不是很好看.而xadmin界面好看,功能更强大,并完全支持Bootstrap主题模板.xadmin内置了丰富的插件功能. ...
 - 【Python3.6+Django2.0+Xadmin2.0系列教程一】环境搭建及项目创建
		
由于工作需要,接触了大半年时间的Django+xadmin框架,一直没空对这块对进行相关的梳理.最近在同事的怂恿下,就在这分享下笔者的学习及工作经验吧. 好了,话不多说,下面开始进入正题: 环境需求: ...
 - python3下Django2.0配置最新xadmin详解
		
1,打开pycharm,创建一个Django项目 2,安装Django,默认是最新版本,pip3 install -i https://pypi.douban.com/simple/ django 3 ...
 - python3.6 + django2.0.6 + xadmin0.6
		
django2.0集成xadmin0.6报错集锦 http://www.lybbn.cn/data/bbsdatas.php?lybbs=50 1.django2.0把from django.core ...
 
随机推荐
- JS 的 new 是个啥?
			
JS 的 new 是个啥? 本文写于 2019 年 11 月 25 日 new关键字在很多语言里面,总是用于把类实例化,可是 JS 之前就没有"类"这个概念呀. 那 JS 的new ...
 - 栈在go语言中实现,及解决388.文件的最长绝对路径的思路
			
今天在LeetCode刷每日一题,遇到了388. 文件的最长绝对路径的思路,这道题让我想到了系统的目录是栈结构,果然在题解中找到了栈的解法(暴力半天没出来,跑去看题解了QWQ). 所以我就捎带复习了一 ...
 - kernel heap bypass smep,smap && 劫持modprobe_path
			
kernel heap bypass smep,smap && 劫持modprobe_path exp1 smep:smep即用户数据不可执行,当 CPU 处于 ring0 模式时,执 ...
 - grpc-java源码环境编译
			
1. Clone 1.1 git clone https://github.com/grpc/grpc-java.git 1.2 idea 打开grpc-java工程 2.compile 2.1 ja ...
 - MySQL用户管理与字符集
			
用户管理与字符集 一.用户管理 用户名的概念 用户名是由两部分组成的 user和host 1.1 创建用户 create user 'yysue'@'192.168.5.38' identified ...
 - vue设计模式
			
vm 的设计模式. mvvm 是 model-view-viewModel 的简写. model 是数据模块,view 是渲染视图,viewModel 是沟通视图和数据模块的桥梁. vue 中使用了哪 ...
 - 【FineBI】增量数据更新语句
			
SELECT * FROM t_abike_user WHERE AddUserTime BETWEEN '2016-11-17 10:49:04' AND '2021-07-31 23:59:59'
 - Java包机制和JavaDoc
			
目录 包机制 JavaDoc 视频课程 包机制 包的本质就是文件夹 为了更好的组织类, Java提供了包机制, 用于区别类名的命名空间, 使项目看起来更加整洁 一般公司庸域名倒置作为包名 为了能够使用 ...
 - bintree
			
Python实现二叉树的建立与遍历 创建(二叉)树节点类 class Node: def __init__(self,data,l=None,r=None): self.val = data self ...
 - atcoder abc 244
			
atcoder abc 244 D - swap hats 给定两个 R,G,B 的排列 进行刚好 \(10^{18}\) 次操作,每一次选择两个交换 问最后能否相同 刚好 \(10^{18}\) 次 ...