首页 > 数据库 >MongoDB与Pymongo深度实践:从基础概念到无限级评论应用示例

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

时间:2024-09-13 17:52:38浏览次数:3  
标签:示例 MongoDB self db collection my document Pymongo id

在这里插入图片描述


文章目录


前言

    随着数据量的爆炸性增长,高效的数据存储与管理成为关键。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>

在这里插入图片描述

标签:示例,MongoDB,self,db,collection,my,document,Pymongo,id
From: https://blog.csdn.net/m0_48173416/article/details/141924160

相关文章

  • 【flask系列】基于flask的 RESTful API示例
    原创xlwin136人工智能教学实践RESTfulAPI(RepresentationalStateTransferApplicationProgrammingInterface)是一种基于REST架构风格的网络应用程序接口。REST是一种设计网络服务的架构风格,它通过使用HTTP协议的通用动词(如GET、POST、PUT、DELETE等)来允许客户端和......
  • 高德地图SDK Android版开发 11 覆盖物示例 4 线
    高德地图SDKAndroid版开发11覆盖物示例4线前言界面布局MapPolyline类常量成员变量初始值创建覆盖物移除覆盖物设置属性加载地图和释放地图MapPolylineActivity类控件响应事件运行效果图前言文本通过创建多个不同线宽的折线和大地曲线,介绍Polyline的使用方法。......
  • C# 标准事件模式示例
    1usingSystem;23namespaceConsoleApp3_Test4{56internalclassAa7{89staticvoidMain(string[]args)10{11Stockstock=newStock("THPW");12stock.Price=27.10M;131......
  • 示例 32: 简单的天气应用
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>WeatherApp</title>......
  • 百度地图SDK Android版开发 11 覆盖物示例 4 线
    百度地图SDKAndroid版开发11覆盖物示例4线前言界面布局MapPolyline类常量成员变量初始值创建覆盖物移除覆盖物设置属性加载地图和释放地图MapPolylineActivity类控件响应事件运行效果图前言文本通过创建多个不同线宽的折线和大地曲线,介绍Polyline的使用方法。......
  • Python 内置函数汇总(使用示例)
    abs(number)求解整数,浮点数绝对值,返回复数模大小aiter()异步的方式遍历可迭代对象的异步迭代器importasynciocount=0asyncdefexample():asyncdefasync_generator():globalcountwhileTrue:count+=1......
  • 《华为防火墙基本配置示例》
    目录华为防火墙基本配置示例: 1. 登录防火墙2. 基本系统配置 3. 安全区域配置4. 策略配置 5. NAT配置(如果需要) 6. 防火墙攻击防范配置 7. 保存配置华为防火墙基本配置示例: 1. 登录防火墙 -通过Console线将电脑与防火墙的Console接口连接......
  • 【抽奖小程序示例代码】
    以下是一个使用Python的Flask框架创建的简单网页抽奖小程序示例代码: fromflaskimportFlask,render_templateimportrandomapp=Flask(__name__)@app.route('/')deflottery():  prizes=["一等奖","二等奖","三等奖","谢谢参与"]  resul......
  • 全国增值税发票查验接口平台-JavaScript发票验真api示例
    全国增值税发票查验接口平台旨在优化纳税服务,加强企业发票管理,确保税收工作的准确性。企业财务可以通过发票查验接口方便快捷的验证增值税发票管理系统开具发票的真伪,以实现发票的自动化管理,减少人工操作失误,提高识别、录入、查验的准确性和工作效率,从而有效防止税务欺诈和逃......
  • <<编码>> 第 4 章 手电筒剖析(Anatomy of a Flashlight) 示例电路
    简单灯泡电路info::操作说明鼠标单击按钮开关切换开合状态另:黄色小点为电流,后同.可通过“菜单–选项–显示电流”控制是否显示primary::在线交互操作链接https://cc.xiaogd.net/?startCircuitLink=https://book.xiaogd.net/code-hlchs-examples/assets/circ......