MongoDB与Pymongo深度实践:从基础概念到无穷级评论应用示例 ...

打印 上一主题 下一主题

主题 642|帖子 642|积分 1926




  

前言

    随着数据量的爆炸性增长,高效的数据存储与管理成为关键。MongoDB,作为NoSQL数据库的佼佼者,凭借其灵活的文档模型、高可扩展性和强大的查询本领,赢得了广泛关注。本博客将深入浅出地介绍MongoDB的根本概念、焦点操作及实际应用,从基础概念到Docker安装,再到pymongo的使用,末了通过无穷级评论功能展示MongoDB在项目开发中的实际应用。

MongoDB官方文档:https://www.mongodb.com/zh-cn/docs/manual/

一、MongoDB

1.根本介绍

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。它介于关系数据库和非关系数据库之间的产物,是非关系数据库当中功能最丰富,最像关系数据库的。
   关系型数据库(Relational Databases)
  

  • 代表产物: MySQL, SQLite, PostgreSQL
  • 重要功能:

    • 数据存储: 高效、安全地存储结构化数据。
    • 关系管理: 支持复杂的数据关系建模,包罗一对一、一对多、多对多等关系。
    • 变乱支持: 确保数据的一致性和完整性,通过变乱控制来实现。
    • ACID特性: 具备原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、长期性(Durability)等特点。

  • 应用场景: 得当须要强数据一致性和复杂查询的企业级应用,如电商、金融系统等。
    NoSQL数据库(Non-Relational Databases)
  

  • 代表产物: Redis
  • 重要功能:

    • 高性能: 通过非关系型数据模型,提供极高的读写速率和吞吐量。
    • 灵活性: 支持多种数据类型,如键值对、文档、列族、图等,以顺应不同的数据模型需求。
    • 可扩展性: 水平扩展本领强,轻松应对大规模数据增长。

  • 应用场景: 适用于对数据一致性要求不那么严酷,但寻求高性能和可扩展性的场景,如缓存、实时消息系统等。
    向量数据库(Vector Databases)
  

  • 代表产物: Elasticsearch (固然通常被认为是搜索引擎,但也可用于向量搜索), FAISS
  • 重要功能:

    • 高级检索: 支持基于向量的相似性搜索,可以大概高效地在海量数据中查找相似的对象或内容。
    • 优化搜索: 通过向量索引和查询优化技术,实现快速且准确的搜索结果。
    • 灵活匹配: 适用于各种非文本内容的搜索,如图像、音频、视频等多媒体数据。

  • 应用场景: 得当须要复杂搜索功能的场景,如推荐系统、图像识别、自然语言处置惩罚等。
      关系型数据库提供强大的数据一致性和关系管理本领,得当结构化数据的处置惩罚;NoSQL数据库以其高性能和灵活性,成为处置惩罚大规模非结构化数据的理想选择;而向量数据库则通过高级检索功能,为须要复杂搜索功能的场景提供相识决方案。
    在实际应用中,还可以根据业务发展和数据量的变革,采取混合数据库架构,结合不同类型数据库的优势,以构建更加高效、灵活、可扩展的数据系统。
2.概念解析

SQL术语/概念MongoDB术语/概念表明/阐明databasedatabase数据库tablecollection数据库表/集合rowdocument数据纪录行/文档columnfield数据字段/域indexindex索引table joins表连接,MongoDB不支持primary keyprimary key主键,MongoDB自动将_id字段设置为主键 3.常见的数据类型

   

  • Object ID: ⽂档ID
  • String: 字符串, 最常⽤, 必须是有效的UTF-8
  • Boolean: 存储⼀个布尔值, true或false
  • Integer: 整数可以是32位或64位, 这取决于服务器
  • Double: 存储浮点值
  • Arrays: 数组或列表, 多个值存储到⼀个键
  • Object: ⽤于嵌⼊式的⽂档, 即⼀个值为⼀个⽂档
  • Null: 存储Null值
  • Timestamp: 时间戳, 表现从1970-1-1到如今的总秒数
  • Date: 存储当前⽇期或时间的UNIX时间格式
  4.Docker 安装

  1. docker search mongo
  2. docker pull mongo
  3. #运行容器
  4. docker run -itd --name mongo -p 27017:27017 mongo --auth
  5. #进入容器
  6. docker exec -it mongo mongosh admin
  7. #使用admin数据
  8. #创建用户
  9. db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
  10. #配制权限
  11. db.auth('admin', '123456')
复制代码
5.常用命令

  1. # 进入mongo容器,使用上文创建的账号
  2. docker exec -it mongo mongosh --username admin --password 123456
  3. #查看已经存在的数据库
  4. show dbs;
  5. #创建数据库
  6. use 数据库名
  7. #删除数据库
  8. db.dropDatabase()
  9. #查看集合
  10. show collections;
  11. #创建集合
  12. db.createCollection("news")
  13. #删除集合
  14. db.runoob.drop()
  15. #添加数据
  16. db.集合名.insert({'id':1,'title':'12'})
  17. db.集合名.insert({'id':1,'title':'12','name':'sdfsd'})
  18. #查询所有
  19. db.集合名.find()
  20. #删除数据
  21. db.集合名.remove({"id":1})
  22. #条件查询
  23. db.集合名.find({"id":1})
复制代码
二、Pymongo

1.根本操作(连接、数据库、集合)

   安装:pip install pymongo
    pymongo连接:
  1. import pymongo
  2. from urllib import parse
  3. username = parse.quote_plus('admin')   # 对用户名进行编码
  4. password = parse.quote_plus('123456')  # 对密码进行编码
  5. database = "admin" # 数据库名称
  6. host     = "123.123.123.123"
  7. port     = "27017"
  8. mongo = pymongo.MongoClient('mongodb://%s:%s@%s:%s/%s' % ( username, password, host, port, database))
复制代码
   数据库操作:
  1. import pymongo
  2. # 数据库连接
  3. mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
  4. # 创建数据库
  5. my_db  = mongo["my_db"]
  6. # 查看数据库列表
  7. print(mongo.list_database_names()) # 上面的 my_db 因为没有内容,所以没有被创建的。
复制代码
   集合操作:
  1. import pymongo
  2. mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
  3. my_db = mongo["my_db"]
  4. my_collection = my_db["my_collection"] # 没有往集合里面保存文档之前,mongdb不会真正创建集合!
  5. # 查看集合列表
  6. print(my_db.list_collection_names())
  7. # 删除集合
  8. my_collection.drop() # 删除成功返回true,如果集合不存在,返回false
复制代码
2.根本操作(增删改查)

   添加:
  1. import pymongo
  2. mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
  3. my_db = mongo["my_db"]
  4. my_collection = my_db["my_collection"]
  5. # 添加一个文档
  6. document = { "name": "xiaoming", "mobile": "13012345678","age":16}
  7. ret = my_collection.insert_one(document)
  8. print(ret.inserted_id) # 返回InsertOneResult对象
  9. # 插入文档时,如果没有指定_id,将自动分配一个唯一的id。
  10. # 添加多个文档
  11. document_list = [
  12. { "name": "xiaoming", "mobile": "13033345678","age":17},
  13. { "name": "xiaohong", "mobile": "13044345678","age":18},
  14. { "name": "xiaohei",  "mobile": "13612345678","age":18},
  15. ]
  16. ret = my_collection.insert_many(document_list)
  17. # 打印文档_id值列表:
  18. print(ret.inserted_ids)
复制代码
   删除:
  1. import pymongo
  2. mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
  3. my_db = mongo["my_db"]
  4. my_collection = my_db["my_collection"]
  5. # 删除一个文档
  6. query = {"name":"xiaoming"}
  7. my_collection.delete_one(query)
  8. # 删除多个文档
  9. query = { "mobile": {"$regex": "^130"} }
  10. ret = my_collection.delete_many(query)
  11. print("删除了%d个文档" % ret.deleted_count)
复制代码
  
  1. import pymongo
  2. from urllib.parse import quote_plus
  3. from bson import ObjectId
  4. if __name__ == "__main__":
  5.    username = quote_plus("mofang")
  6.    password = quote_plus("123456")
  7.    # 获取数据库连接对象
  8.    mongo = pymongo.MongoClient(f"mongodb://{username}:{password}@127.0.0.1:27017/mofang")
  9.    mofang = mongo["mofang"]
  10.    user_list = mofang["user_list"]
  11.    """删除文档"""
  12.    query = {"_id": ObjectId("60d925e127bd4b7769251002")}
  13.    ret = user_list.delete_one(query)
  14.    print(ret)
  15.    print(ret.deleted_count)
  16.    """删除多个文档"""
  17.    query = {"name": "xiaolan"}
  18.    ret = user_list.delete_many(query)
  19.    print(ret.deleted_count)
复制代码
   更新:
  1. import pymongo
  2. mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
  3. my_db = mongo["my_db"]
  4. my_collection = my_db["my_collection"]
  5. # 更新一个文档
  6. query = { "name": "xiaoming" }
  7. data = { "$set": { "age": 18 } }
  8. my_collection.update_one(query, data)
  9. # 更新所有文档
  10. query = { "mobile": {"$regex": "^130"} }
  11. data = { "$set": { "age": 18 } }
  12. my_collection.update_many(query, data)
复制代码
   查询:
  1. import pymongo
  2. mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
  3. my_db = mongo["my_db"]
  4. my_collection = my_db["my_collection"]
  5. # 查看一个文档
  6. ret = my_collection.find_one()
  7. print(ret)
  8. # 查看所有文档
  9. for document in my_collection.find():
  10.    print(document)
  11. # 查看文档部分字段,find和find_one的第二个参数表示控制字段的显示隐藏,1为显示,0为隐藏
  12. for document in my_collection.find({},{ "_id": 0, "name": 1, "mobile": 1 }):
  13.    print(document)
  14. # 条件查询
  15. query = { "age": 18,"name":'22' }
  16. document_list = my_collection.find(query)
  17. for document in document_list:
  18.    print(document)
  19. # 比较运算符
  20. query = { "age": {"$gt":17} }
  21. document_list = my_collection.find(query)
  22. for document in document_list:
  23.    print(document)
  24. # 排序显示
  25. # 单个字段排序:
  26. #         sort("键", 1) 升序
  27. #         sort("键",-1) 降序
  28. # 多个字段排序:
  29. #       sort([("键1",1),("键2",-1)])
  30. document_list = my_collection.find().sort("age",-1)
  31. for document in document_list:
  32.    print(document)
  33.    
  34. # 限制查询结果数量
  35. document_list = my_collection.find().limit(3)
  36. print(document_list)
  37. # 偏移、跳过
  38. #    skip(int)
  39. start = (page -1)*page_size
  40. document_list = my_collection.find().limit(3).skip(3) # 从第3篇文档开始获取3篇文档
  41. print(document_list)
  42. # 自定义条件函数
  43. document_list = my_collection.find({"$where":"this.age==18"})
  44. print(document_list)
复制代码

三、MongoDB应用示例:无穷级评论

1.MongoDB 工具类

  1. # tools/mongodb.py
  2. import pymongo
  3. from urllib import parse
  4. class Mongodb():
  5.     def __init__(self):
  6.         self.username = parse.quote_plus('admin')  # 对用户名进行编码
  7.         self.password = parse.quote_plus('123456')  # 对密码进行编码
  8.         self.database = "admin"  # 数据库名称
  9.         self.host = "120.46.9.231"
  10.         self.port = "27017"
  11.         self.mongo = pymongo.MongoClient(
  12.             'mongodb://%s:%s@%s:%s/%s' % (self.username, self.password, self.host, self.port, self.database))
  13.         self.my_db = self.mongo["my_db"]
  14.     def add_data(self, name, data):
  15.         self.my_collection = self.my_db[name]
  16.         ret = self.my_collection.insert_one(data)
  17.         print(ret.inserted_id)
  18.         return ret.inserted_id
  19.     def find_where(self, name, query, pagesize, start):
  20.         self.my_collection = self.my_db[name]
  21.         return self.my_collection.find(query).limit(pagesize).skip(start)
  22.     def find_all(self, name, query):
  23.         self.my_collection = self.my_db[name]
  24.         return self.my_collection.find(query)
  25.     def delete_all(self,name,query):
  26.         self.my_collection = self.my_db[name]
  27.         return self.my_collection.delete_many(query)
  28. mdb = Mongodb()
  29. # ret = db.add_data('comment',{"title":"234234","userid":1})
  30. # print(ret)
  31. # res = db.find_all('comment')
  32. # for i in res:
  33. #     print(i)
复制代码
2.实现无穷级评论逻辑

  1. from rest_framework.views import APIView
  2. from rest_framework.response import Response
  3. # Create your views here.
  4. from tools.mongodb import mdb
  5. def generate_tree(source, parent):
  6.     tree = []
  7.     for item in source:
  8.         if item["pid"] == parent:
  9.             item["children"] = generate_tree(source, item["id"])
  10.             tree.append(item)
  11.     return tree
  12. class CommemtView(APIView):
  13.     def delete(self,request):
  14.         mdb.delete_all('comments',{"topid":0})
  15.         mdb.delete_all('comments',{"topid":1})
  16.         return Response({"code": 200,"msg":"删除所有顶级数据。"})
  17.     def post(self, request):
  18.         mdb.add_data('comments', {'id': 1, "title": "第一条评论", "userid": 1, "pid": 0, "topid": 0})
  19.         mdb.add_data('comments', {'id': 2, "title": "第二条评论", "userid": 1, "pid": 0, "topid": 0})
  20.         mdb.add_data('comments', {'id': 5, "title": "第三条评论", "userid": 1, "pid": 0, "topid": 0})
  21.         mdb.add_data('comments', {'id': 3, "title": "顶级评论1下回复id=1的评论", "userid": 1, "pid": 1, "topid": 1})
  22.         mdb.add_data('comments', {'id': 4, "title": "顶级评论1下回复id=3的评论", "userid": 1, "pid": 3, "topid": 1})
  23.         return Response({"code": 200,"msg":"POST添加评论成功。"})
  24.     def get(self, request):
  25.         page = request.GET.get('page', 1)
  26.         page_size = 10
  27.         start = (int(page) - 1) * page_size
  28.         data = mdb.find_where('comments', {"pid": 0}, page_size, start)
  29.         # mdata = list(mdb.find_all('comments',{"pid":0}))
  30.         # count = len(mdata)
  31.         list1 = []
  32.         for i in data:
  33.             dict = {"id": i['id'], 'label': i['title'], 'pid': i['pid']}
  34.             list1.append(dict)
  35.             son = mdb.find_all('comments', {"topid": i['id']})
  36.             for j in son:
  37.                 list1.append({"id": j['id'], 'label': j['title'], 'pid': j['pid']})
  38.         print(data)
  39.         resdata = generate_tree(list1, 0)
  40.         return Response({"code": 200, 'reslist': resdata, 'tcount': 99})
复制代码
3.Vue树形结构展示无穷级评论

   

  1. <template>
  2.   哈哈哈
  3.   <div class="comment-tree">
  4.     <el-tree
  5.       :data="mydata"
  6.       :props="defaultProps"
  7.       node-key="id"
  8.       default-expand-all
  9.     ></el-tree>
  10.   </div>
  11.   <!-- mydata === {{mydata}} -->
  12.   <!-- reslist === {{reslist}} -->
  13. </template>
  14. <script>
  15. import http from '../http'
  16. export default {
  17.    
  18.   data() {
  19.     return {
  20.       mydata: [],
  21.       reslist: [
  22.         {
  23.           id: 1,
  24.           label: "第一条评论",
  25.           pid: 0,
  26.           children: [
  27.             {
  28.               id: 3,
  29.               label: "顶级评论1下回复id=1的评论",
  30.               pid: 1,
  31.               children: [
  32.                 {
  33.                   id: 4,
  34.                   label: "顶级评论1下回复id=3的评论",
  35.                   pid: 3,
  36.                   children: []
  37.                 }
  38.               ]
  39.             }
  40.           ]
  41.         },
  42.         {
  43.           id: 2,
  44.           label: "第二条评论",
  45.           pid: 0,
  46.           children: []
  47.         },
  48.         {
  49.           id: 5,
  50.           label: "第三条评论",
  51.           pid: 0,
  52.           children: []
  53.         }
  54.       ],
  55.       defaultProps: {
  56.         children: 'children',
  57.         label: 'label',
  58.         disabled: false
  59.       }
  60.     };
  61.   },
  62.   mounted () {
  63.     http.get('/comment/').then(res => {
  64.         console.log("res.data.reslist===>",res.data.reslist);
  65.         this.mydata = res.data.reslist;
  66.     });
  67.   },
  68. };
  69. </script>
  70. <style scoped>
  71. .comment-tree {
  72.   max-width: 800px;
  73.   margin: 20px auto;
  74. }
  75. </style>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表