前言
随着数据量的爆炸性增长,高效的数据存储与管理成为关键。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 安装
- docker search mongo
- docker pull mongo
- #运行容器
- docker run -itd --name mongo -p 27017:27017 mongo --auth
- #进入容器
- docker exec -it mongo mongosh admin
- #使用admin数据
- #创建用户
- db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
- #配制权限
- db.auth('admin', '123456')
复制代码 5.常用命令
- # 进入mongo容器,使用上文创建的账号
- docker exec -it mongo mongosh --username admin --password 123456
- #查看已经存在的数据库
- show dbs;
- #创建数据库
- use 数据库名
- #删除数据库
- db.dropDatabase()
- #查看集合
- show collections;
- #创建集合
- db.createCollection("news")
- #删除集合
- db.runoob.drop()
- #添加数据
- db.集合名.insert({'id':1,'title':'12'})
- db.集合名.insert({'id':1,'title':'12','name':'sdfsd'})
- #查询所有
- db.集合名.find()
- #删除数据
- db.集合名.remove({"id":1})
- #条件查询
- db.集合名.find({"id":1})
复制代码 二、Pymongo
1.根本操作(连接、数据库、集合)
安装:pip install pymongo
pymongo连接:
- import pymongo
- from urllib import parse
- username = parse.quote_plus('admin') # 对用户名进行编码
- password = parse.quote_plus('123456') # 对密码进行编码
- database = "admin" # 数据库名称
- host = "123.123.123.123"
- port = "27017"
- mongo = pymongo.MongoClient('mongodb://%s:%s@%s:%s/%s' % ( username, password, host, port, database))
复制代码 数据库操作:
- import pymongo
- # 数据库连接
- mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
- # 创建数据库
- my_db = mongo["my_db"]
- # 查看数据库列表
- print(mongo.list_database_names()) # 上面的 my_db 因为没有内容,所以没有被创建的。
复制代码 集合操作:
- import pymongo
- mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
- my_db = mongo["my_db"]
- my_collection = my_db["my_collection"] # 没有往集合里面保存文档之前,mongdb不会真正创建集合!
- # 查看集合列表
- print(my_db.list_collection_names())
- # 删除集合
- my_collection.drop() # 删除成功返回true,如果集合不存在,返回false
复制代码 2.根本操作(增删改查)
添加:
- import pymongo
- mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
- my_db = mongo["my_db"]
- my_collection = my_db["my_collection"]
- # 添加一个文档
- document = { "name": "xiaoming", "mobile": "13012345678","age":16}
- ret = my_collection.insert_one(document)
- print(ret.inserted_id) # 返回InsertOneResult对象
- # 插入文档时,如果没有指定_id,将自动分配一个唯一的id。
- # 添加多个文档
- document_list = [
- { "name": "xiaoming", "mobile": "13033345678","age":17},
- { "name": "xiaohong", "mobile": "13044345678","age":18},
- { "name": "xiaohei", "mobile": "13612345678","age":18},
- ]
- ret = my_collection.insert_many(document_list)
- # 打印文档_id值列表:
- print(ret.inserted_ids)
复制代码 删除:
- import pymongo
- mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
- my_db = mongo["my_db"]
- my_collection = my_db["my_collection"]
- # 删除一个文档
- query = {"name":"xiaoming"}
- my_collection.delete_one(query)
- # 删除多个文档
- query = { "mobile": {"$regex": "^130"} }
- ret = my_collection.delete_many(query)
- print("删除了%d个文档" % ret.deleted_count)
复制代码 - import pymongo
- from urllib.parse import quote_plus
- from bson import ObjectId
- if __name__ == "__main__":
- username = quote_plus("mofang")
- password = quote_plus("123456")
- # 获取数据库连接对象
- mongo = pymongo.MongoClient(f"mongodb://{username}:{password}@127.0.0.1:27017/mofang")
- mofang = mongo["mofang"]
- user_list = mofang["user_list"]
- """删除文档"""
- query = {"_id": ObjectId("60d925e127bd4b7769251002")}
- ret = user_list.delete_one(query)
- print(ret)
- print(ret.deleted_count)
- """删除多个文档"""
- query = {"name": "xiaolan"}
- ret = user_list.delete_many(query)
- print(ret.deleted_count)
复制代码 更新:
- import pymongo
- mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
- my_db = mongo["my_db"]
- my_collection = my_db["my_collection"]
- # 更新一个文档
- query = { "name": "xiaoming" }
- data = { "$set": { "age": 18 } }
- my_collection.update_one(query, data)
- # 更新所有文档
- query = { "mobile": {"$regex": "^130"} }
- data = { "$set": { "age": 18 } }
- my_collection.update_many(query, data)
复制代码 查询:
- import pymongo
- mongo = pymongo.MongoClient("mongodb://127.0.0.1:27017/")
- my_db = mongo["my_db"]
- my_collection = my_db["my_collection"]
- # 查看一个文档
- ret = my_collection.find_one()
- print(ret)
- # 查看所有文档
- for document in my_collection.find():
- print(document)
- # 查看文档部分字段,find和find_one的第二个参数表示控制字段的显示隐藏,1为显示,0为隐藏
- for document in my_collection.find({},{ "_id": 0, "name": 1, "mobile": 1 }):
- print(document)
- # 条件查询
- query = { "age": 18,"name":'22' }
- document_list = my_collection.find(query)
- for document in document_list:
- print(document)
- # 比较运算符
- query = { "age": {"$gt":17} }
- document_list = my_collection.find(query)
- for document in document_list:
- print(document)
- # 排序显示
- # 单个字段排序:
- # sort("键", 1) 升序
- # sort("键",-1) 降序
- # 多个字段排序:
- # sort([("键1",1),("键2",-1)])
- document_list = my_collection.find().sort("age",-1)
- for document in document_list:
- print(document)
-
- # 限制查询结果数量
- document_list = my_collection.find().limit(3)
- print(document_list)
- # 偏移、跳过
- # skip(int)
- start = (page -1)*page_size
- document_list = my_collection.find().limit(3).skip(3) # 从第3篇文档开始获取3篇文档
- print(document_list)
- # 自定义条件函数
- document_list = my_collection.find({"$where":"this.age==18"})
- print(document_list)
复制代码 三、MongoDB应用示例:无穷级评论
1.MongoDB 工具类
- # tools/mongodb.py
- import pymongo
- from urllib import parse
- class Mongodb():
- def __init__(self):
- self.username = parse.quote_plus('admin') # 对用户名进行编码
- self.password = parse.quote_plus('123456') # 对密码进行编码
- self.database = "admin" # 数据库名称
- self.host = "120.46.9.231"
- self.port = "27017"
- self.mongo = pymongo.MongoClient(
- 'mongodb://%s:%s@%s:%s/%s' % (self.username, self.password, self.host, self.port, self.database))
- self.my_db = self.mongo["my_db"]
- def add_data(self, name, data):
- self.my_collection = self.my_db[name]
- ret = self.my_collection.insert_one(data)
- print(ret.inserted_id)
- return ret.inserted_id
- def find_where(self, name, query, pagesize, start):
- self.my_collection = self.my_db[name]
- return self.my_collection.find(query).limit(pagesize).skip(start)
- def find_all(self, name, query):
- self.my_collection = self.my_db[name]
- return self.my_collection.find(query)
- def delete_all(self,name,query):
- self.my_collection = self.my_db[name]
- return self.my_collection.delete_many(query)
- mdb = Mongodb()
- # ret = db.add_data('comment',{"title":"234234","userid":1})
- # print(ret)
- # res = db.find_all('comment')
- # for i in res:
- # print(i)
复制代码 2.实现无穷级评论逻辑
- from rest_framework.views import APIView
- from rest_framework.response import Response
- # Create your views here.
- from tools.mongodb import mdb
- def generate_tree(source, parent):
- tree = []
- for item in source:
- if item["pid"] == parent:
- item["children"] = generate_tree(source, item["id"])
- tree.append(item)
- return tree
- class CommemtView(APIView):
- def delete(self,request):
- mdb.delete_all('comments',{"topid":0})
- mdb.delete_all('comments',{"topid":1})
- return Response({"code": 200,"msg":"删除所有顶级数据。"})
- def post(self, request):
- mdb.add_data('comments', {'id': 1, "title": "第一条评论", "userid": 1, "pid": 0, "topid": 0})
- mdb.add_data('comments', {'id': 2, "title": "第二条评论", "userid": 1, "pid": 0, "topid": 0})
- mdb.add_data('comments', {'id': 5, "title": "第三条评论", "userid": 1, "pid": 0, "topid": 0})
- mdb.add_data('comments', {'id': 3, "title": "顶级评论1下回复id=1的评论", "userid": 1, "pid": 1, "topid": 1})
- mdb.add_data('comments', {'id': 4, "title": "顶级评论1下回复id=3的评论", "userid": 1, "pid": 3, "topid": 1})
- return Response({"code": 200,"msg":"POST添加评论成功。"})
- def get(self, request):
- page = request.GET.get('page', 1)
- page_size = 10
- start = (int(page) - 1) * page_size
- data = mdb.find_where('comments', {"pid": 0}, page_size, start)
- # mdata = list(mdb.find_all('comments',{"pid":0}))
- # count = len(mdata)
- list1 = []
- for i in data:
- dict = {"id": i['id'], 'label': i['title'], 'pid': i['pid']}
- list1.append(dict)
- son = mdb.find_all('comments', {"topid": i['id']})
- for j in son:
- list1.append({"id": j['id'], 'label': j['title'], 'pid': j['pid']})
- print(data)
- resdata = generate_tree(list1, 0)
- return Response({"code": 200, 'reslist': resdata, 'tcount': 99})
复制代码 3.Vue树形结构展示无穷级评论
- <template>
- 哈哈哈
- <div class="comment-tree">
- <el-tree
- :data="mydata"
- :props="defaultProps"
- node-key="id"
- default-expand-all
- ></el-tree>
- </div>
- <!-- mydata === {{mydata}} -->
- <!-- reslist === {{reslist}} -->
- </template>
- <script>
- import http from '../http'
- export default {
-
- data() {
- return {
- mydata: [],
- reslist: [
- {
- id: 1,
- label: "第一条评论",
- pid: 0,
- children: [
- {
- id: 3,
- label: "顶级评论1下回复id=1的评论",
- pid: 1,
- children: [
- {
- id: 4,
- label: "顶级评论1下回复id=3的评论",
- pid: 3,
- children: []
- }
- ]
- }
- ]
- },
- {
- id: 2,
- label: "第二条评论",
- pid: 0,
- children: []
- },
- {
- id: 5,
- label: "第三条评论",
- pid: 0,
- children: []
- }
- ],
- defaultProps: {
- children: 'children',
- label: 'label',
- disabled: false
- }
- };
- },
- mounted () {
- http.get('/comment/').then(res => {
- console.log("res.data.reslist===>",res.data.reslist);
- this.mydata = res.data.reslist;
- });
- },
- };
- </script>
- <style scoped>
- .comment-tree {
- max-width: 800px;
- margin: 20px auto;
- }
- </style>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |