当前位置: 首页 > news >正文

数据库——MongoDB

一、介绍

1. MongoDB 概述

MongoDB 是一款由 C++ 语言编写的开源 NoSQL 数据库,采用分布式文件存储设计。作为介于关系型和非关系型数据库之间的产品,它是 NoSQL 数据库中最接近传统关系数据库的解决方案,同时保留了 NoSQL 的灵活性和扩展性。

核心特性:
  • 文档导向存储:数据以类似 JSON 的 BSON 格式存储

  • 无固定表结构:不需要预先定义严格的表结构

  • 多语言支持:提供 Python、Node.js、Java、C++、PHP、C# 等主流语言的驱动

  • 应用场景广泛:适用于大数据、内容管理、持续交付、移动应用、社交网络、用户数据管理等领域

2. MongoDB 相对于关系型数据库(RDBMS)的优势

优势说明
灵活的数据模型无固定结构,数据结构为键值对(key:value)形式,文档类似 JSON 对象
嵌套数据支持字段值可包含其他文档、数组及文档数组,使数据结构更清晰
无复杂关联不需要维护表与表之间的内在关联关系,简化数据模型
强大的查询能力提供类似 SQL 的丰富查询功能,支持基于文档的动态查询
高性能与可扩展易于调优和扩展,具备高性能、高可用性和可伸缩性特性
对象映射自然应用程序对象与数据库对象呈现天然对应关系
存储方式灵活支持基于内存或硬盘文件的存储方式
完善的特性支持提供丰富的查询操作、索引支持,4.0+版本支持多文档事务

3. SQL 与 MongoDB 核心概念对比

SQL 术语MongoDB 术语说明
数据库 (Database)数据库 (Database)数据存储的最高层级
表 (Table)集合 (Collection)数据记录的容器
行/记录 (Row)文档 (Document)单条数据记录,采用 JSON 结构
列/字段 (Column)字段/键 (Field)数据记录的属性
主键 (Primary Key)对象ID (ObjectId)默认主键格式为 _id: ObjectId("...")
索引 (Index)索引 (Index)加速查询的数据结构

4. 适用场景推荐

MongoDB 特别适合以下场景:
  • 需要快速迭代开发的项目

  • 数据结构频繁变化的业务

  • 处理大量非结构化或半结构化数据

  • 需要水平扩展的高流量应用

  • 内容管理系统和博客平台

  • 实时分析和数据处理

传统 SQL 仍更适合:
  • 需要复杂事务处理的应用

  • 数据结构高度规范化的场景

  • 已有成熟的关系型数据模型

提示:MongoDB 4.0+ 已支持多文档 ACID 事务,但在复杂事务场景下仍需谨慎评估性能影响。

 

二、MongoDB基本操作

1.库管理

显示所有数据库列表:空数据库不会显示,或者说空数据库已经被MongoDB回收了。

show dbs
show databases

切换数据库,如果数据库不存在则创建数据库

use <database>

查看当前工作的数据库

db //是db.getName()的简写

删除当前数据库,如果数据库不存在,也会返回{"ok":1}

use <db>    // 先切换到要删除的数据库种,然后才能删除数据库
db.dropDatabase()

查看当前数据库状态

db.stats()

在 MongoDB 中,最重要的核心是文档,如果一个库或者一个库下的集合中的文档全部被删除了,则这个库和这个集合就会 MongoDB回收删除。

2.集合管理

创建集合

在 mongodb 中其实不需要专门创建集合,直接添加文档,mongodb 也会自动生成集合

// name 为必填参数,options为可选参数。capped若设置值为true,则size必须也一并设置
db.createCollection(name=<集合名称>,options={capped:<boolean>,    // 创建固定集,固定集指限制固定数据大小的集合,当数据达到最大值会自动覆盖最早的文档内容size:<bytes_size>,    // 指定固定集合存储的最大字节数,单位:字节数max:<collection_size>    // 指定固定集合中包含文档的最大数量,单位:字节数});// 添加文档到不存在的集合中,mongodb会自动创建集合,
// db.<集合名称>.insert(要存储的json数据)use book_info
db.courses.insert({"name":"python入门","price":31.4})
集合列表
show collections    // 或 show tables 或 db.getCollectionNames()
删除集合
db.集合名称.drop()
查看集合
db.getCollection("集合")
db.集合名称
查看集合创建信息
db.printCollectionStats()

三、文档管理

1.数据类型

类型描述
ObjectID用于存储文档的ID,相当于主键,区分文档的唯一字段,MongoDB中就是一个对象的返回值
String字符串是最常用的数据类型,MongoDB中的字符串必须是UTF-8.
Integer整数类型用于存储数值。整数可以是32位,也可以是64位,这取决于你的服务器。
Double双精度类型用于存储浮点值,MongoDB中没有float浮点数这个说法
Boolean布尔类型用于存储布尔值:true/false
Arrays将数组、列表或多个值存储到一个键
Timestamp时间戳,用于记录文档何时被修改或创建。Date(),Timestamp(),ISODate()
Object

用于嵌入文档, 相当于子属性是另一个json文档而已,这种方式就可以实现嵌套

Null

空值,相当于pythonNone

Symbol

与字符串用法相同,常用于某些使用特殊符号的语言,二进制

Date

用于以UNIX时间格式存储当前日期或时间。

Binary data二进制数据,常用于保存文件的内容,往往是图片,数据本身。
Code用于将 JavaScript代码存储到文档中
Regular expression正则表达式

2.添加文档

文档的数据结构和JSON基本一样。所有存储在集合中的数据在内部存储的格式都是BSON格式。

BSON是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。

//添加文档
//方式1
db.<集合名称>.insert(<document>) // document就是一个json格式的数据//方式2
db.<集合名称>.insertOne(<document>) // 如果文档存在_id主键为更新数据,否则就添加数据。//方式3
//一次性添加多个文档,多次给同一个集合
db.<集合名称>.insertMany([<document>,<document>,...])
use person// 添加一条数据
db.user_list.insert({"name":"老李", "age":33, "sex":true, "child":{"name":"小灰灰","age":3}});
// WriteResult({ "nInserted" : 1 })// 添加一条数据
db.user_list.insertOne({"name":"小张", "age":18, "sex":true});
// {
// 	"acknowledged" : true,
// 	"insertedId" : ObjectId("605021e6d5c7a55cc95c1cb7")
// }// 添加多条数据
document1 = {"name":"小蓝", "age":16}
document2 = {"name":"小广", "age":16}
db.user_list.insertMany([document1, document2]);// {
// 	"acknowledged" : true,
// 	"insertedIds" : [
// 		ObjectId("60502235d5c7a55cc95c1cba"),
// 		ObjectId("60502235d5c7a55cc95c1cbb")
// 	]
// }
db.user_list.find()

3.删除文档

// 方式1
db.<集合名称>.remove(<query>,  // remove的条件,一般写法:{"属性":{条件:值}},如果不填写条件,删除所有文档{justOne: <boolean>,      // 可选删除,是否只删除查询到的第一个文档,默认为false,删除所有writeConcern: <document> // 可选参数,抛出异常的级别。}
)// 方式2: 删除一条数据
db.<集合名称>.deleteOne(<query>,  // removed的条件,一般写法:{"属性":{条件:值}},如果不填写条件,删除所有文档{justOne: <boolean>,      // 可选删除,是否只删除查询到的第一个文档,默认为false,删除所有writeConcern: <document> // 可选参数,抛出异常的级别。}
)
// 方式3:删除多条数据
db.<集合名称>.deleteMany(<query>,  // removed的条件,一般写法:{"属性":{条件:值}},如果不填写条件,删除所有文档{justOne: <boolean>,      // 可选删除,是否只删除查询到的第一个文档,默认为false,删除所有writeConcern: <document> // 可选参数,抛出异常的级别。}
)
// 添加多条测试数据
document1 = {"name":"小黑", "age":16}
document2 = {"name":"小白", "age":16}
db.user_list.insertMany([document1, document2]);// 删除满足条件的第一条数据
// 条件 {"age":{$eq:16}}   相当于 age == 16
// db.user_list.remove({"age":{$eq:16}},{"justOne":true})
// 删除满足条件的所有数据,条件中$wq可以不写
// db.user_list.remove({"age":16}); // 等于可以省略不写,相当于 db.user_list.remove({"age":{$eq:16}});// 删除一条
db.user_list.deleteOne({"age": 16})
// 删除多条
db.user_list.deleteMany({"age": 16})

4.查询文档

// 获取一条
db.集合名称.findOne(<query>,     // 查询条件,删除、查询、修改都需要条件、条件写法基本一样的。{<key>: 0, // 隐藏指定字段,例如:"_id":0,<key>: 1, // 显示指定字段,例如:"title":1,....}
)
// 获取多条
db.集合名称.find(<query>,      // 查询条件{<key>: 0, // 隐藏指定字段,例如:"_id":0,<key>: 1, // 显示指定字段,例如:"title":1,....}
)// 以易读的方式来格式化显示读取到的数据,只能在find方法后面使用。
db.集合名称.find().pretty()
// 切换数据库
use person// 添加测试数据
docs = [{"name": "小黄", "sex": 0, "age": 15, "mobile": "13301234568"},{"name": "小飞", "sex": 1, "age": 16, "mobile": "1351234568"},{"name": "小龙", "sex": 1, "age": 19, "mobile": "15001234568"},{"name": "小绵羊", "sex": 0, "age": 13, "mobile": "15001234568"}
]
db.user_list.insertMany(docs);// 查询一条数据
db.user_list.findOne()  // 获取集合中第一条数据
db.user_list.findOne({})  // 同上
db.user_list.findOne({},{_id:0})  // 获取集合中第一条数据,并隐藏_id
db.user_list.findOne({},{_id:0, name:1, mobile:1})  // 获取集合中第一条数据,只查询文档的name和mobile属性的数据
db.user_list.findOne({name:"小飞"}, {_id:0, name:1, mobile:1})
db.user_list.findOne({name:"小龙", age:19})// 查询多条数据
db.user_list.find()
db.user_list.find().pretty()
db.user_list.find({sex:1})
db.user_list.find({sex:0}, {_id:0, name:1, mobile:1})

5.比较运算

操作

格式

语法例子

SQL中的类似语句

等于

{<key>:<val>}

{<key>:{$eq:<val>}}

db.集合.find({"name":"xiaoming"})

where name = 'xiaoming'

小于

{<key>:{$lt:<val>}}

db.集合.find({"age":{$lt:17}})

where age < 17

小于或等于

{<key>:{$lte:<val>}}

db.集合.find({"age":{$lte:17}})

where age <= 17

大于

{<key>:{$gt:<val>}}

db.集合.find({"age":{$gt:17}})

where age > 17

大于或等于

{<key>:{$gte:<val>}}

db.集合.find({"age":{$gte:17}})

where age >= 17

不等于

{<key>:{$ne:<val>}}

db.集合.find({"age":{$ne:17}})

where age != 17

包含

{<key>:{$in:[<val>...]}}

db.集合.find({"age":{$in:[1,2,3]}})

where age in (1,2,3)

db.user_list.find({"age": {$lte:18}})  // 小于等于
db.user_list.find({"age": {$gte:18}})  // 大于等于
db.user_list.find({"age": {$in:[16,33]}})// 添加测试数据
db.user_list.insert({"name":"老王", "age":32, "sex":true, "child":{"name":"小王", "age":4}});
db.user_list.insert({"name":"老张", "age":33, "sex":true, "child":{"name":"小张", "age":5}});db.user_list.find({"child.age": {$gt:3}})
db.user_list.find({"child.age": {$in:[3, 5]}})

6.逻辑运算

$and

{<key>:<val>,<key>:<val>,...}

{$and: [{key:{$运算符:<val>}},....]}

db.集合.find({key1:value1, key2:value2})

$or

{$or: [{<key>: {$运算符:<val>}}, ....]}

db.集合.find({$or: [{key1: value1}, {key2:value2}]})

$and$or

{<key>:<val>, $or: [{<key>: {<$运算符>:<val>}},...]}

{$and:[{$or:[{<key>:{<$运算符>:<val>}},..]},$or:[{<key>:{<$运算符>:<val>}},..]}]}

db.集合.find({key1:value1, $or: [{key1: value1}, {key2:value2}]})

$not

{<key>:{$not:{<$运算符>:<val>}}}

$not操作符不支持$regex正则表达式操作

// 查询age=19 并且 sex=1
db.user_list.find({$and:[{"age":{$eq:19}},{"sex":{$eq:1}}]
})
// 简写:
db.user_list.find({$and:[{"age":19},{"sex":1}]
})
// 继续简写;
db.user_list.find({"age":19, "sex":1})// 查询age=16或者age=18
db.user_list.find({$or:[{"age":{$eq:16}},{"age":{$eq:18}}]
})// 查询年龄!=16的
db.user_list.find({"age":{$not:{$eq:16}}})
db.user_list.find({"age":{$ne:16}})// 查询age=33的男生 或者 age=19的男生
db.user_list.find({"sex":1,$or:[{"age":19},{"age":33}]
});db.user_list.find({"sex":1,"age":{$in:[19,33]}
});db.user_list.find({$or:[{$and:[{"sex":1},{"age":19}]},{$and:[{"sex":1},{"age":33}]},]
});db.user_list.find({$or:[{"sex":1,"age":19},{"sex":1,"age":33},]
});

 7.排序显示

db.集合.find().sort({<key>:1})  // 升序,默认为升序,从小到大
db.集合.find().sort({<key>:-1}) // 倒序db.user_list.find().sort({age:-1});
db.user_list.find().sort({age:-1, sex:1});

8.字段投影

find()方法默认将返回文档的所有数据,但是可以通过设置find()的第二个参数projection,设置值查询部分数据。

// 只显示人名
db.user_list.find({},{'name':1,'_id':0})

9.分页查询

limit方法用于限制返回结果的数量,skip方法用于设置返回结果的开始位置

// db.集合.find(...).limit(结果数量).skip(跳过数量)db.user_list.find({},{"_id":0,"name":1,"age":1}).sort({"age":1}).limit(5);
db.user_list.find({},{"_id":0,"name":1,"age":1}).sort("age":1}).limit(5).skip(5);

10.更新文档

操作

语法

说明

$inc

db.集合.update({<key1>:<val1>},{$inc:{<key2>:<val2>}})

更新key1=val1的文档中key2的值为val2,类似python的递增递减:{ $inc:{<key2>:-<val2>} }

$set

db.集合.update({<key1>:<val>}, {$set:{<key2>:<val2>}})

更新key1=val1的文档中key2的值为val2,如果key2不存在则新增对应键值对

$unset

db.集合.update({<key1>:<val>}, {$unset:{<key2>:<val2>}})

移除key1=val1的文档中key2=val2这个键值对

$push

db.集合.update({<key1>:<val>}, {$push:{<key2>:<val2>}})

key1=val1的文档中key2列表增加1个数组成员val2key2必须是数组。

$pull

db.集合.update({<key1>:<val>}, {$pull:{<key2>:<val2>}})

push相反,给key1=val1的文档中key2列表删除1个指定成员val2

$pop

db.集合.update({<key1>:<val>}, {$pop:{<key2>:<val2>}})

key1=val1的文档中key2列表移除第一个或最后一个成员。val2只能是1(最后面)-1(最前面),与python相反

// db.user_list.insert({"name":"老李", "age":33, "sex":true, "child":{"name":"小灰灰","age":3}});
// $inc
// 把老李的年龄加10岁
db.user_list.update({"name":"老李"},{$inc:{"age":10}}); // 更新一条
db.user_list.find({"name": "老李"})// 添加测试数据
documents = [{"name":"小明", "age":12},{"name":"小明", "age":20},
]
db.user_list.insertMany(documents)db.user_list.updateMany({"name":"小明"},{$inc:{"age":10}}); // 更新多条// 把老李的孩子年龄加10岁
db.user_list.update({"name":"老李"},{$inc:{"child.age":10}});// $set
//更新老李的手机号码
db.user_list.update({"name":"老李"},{$set:{"mobile":"18012312312"}}); // 更新一条
// 更新老李孩子的手机号码
db.user_list.update({"name":"老李"},{$set:{"child.mobile":"18012312312"}});// $unset
// 移除老李的性别键值对
db.user_list.update({"name":"老李"},{$unset:{"sex":true}});// $push
db.user_list.update({"name":"老李"},{$set:{"love":["TV","game"]}});
db.user_list.update({"name":"老李"},{$push:{"love":"code"}}); // 往列表属性中追加成员// $addToSet 结合 $each 批量添加列表中的每一个元素
db.user_list.update({"name":"老李"},{$addToSet:{"love":{$each:["code","music","TV"]}}});// $pull
db.user_list.update({"name":"老李"},{$pull:{"love":"TV"}});// $pop
db.user_list.update({"name":"老李"},{$pop:{"love":-1}}); // 左边移除列表的第一个成员
db.user_list.update({"name":"老李"},{$pop:{"love":1}}); // 右边移除列表的最后一个成员// $rename 字段名重命名
db.user_list.update({"name":"老李"},{$rename:{"love":"lve"}});

 四、第三方客户端-pymongo

1.概述

pymongo 是 MongoDB的一个 python 驱动程序,允许你使用 python 来操作 mongodb 数据库。下面将为你介绍pymongo的基本使用,包括安装、连接数据库、创建集合、插入文档、查询文档、更新文档和删除文档。

2.连接数据库

需要安装pymongo:pip install pymongo

from pymongo import MongoClientclient = MongoClient('localhost', 27017)  # 连接到本地MongoDB
db = client['py_spider']  # 选择或创建一个数据库

3.文档插入

插入数据时如果集合不存在则新建集合

from pymongo import MongoClientmongo_client = MongoClient()
collection = mongo_client['py_spider']['person']# 插入单个文档
person_info = {"name": "John", "address": "长沙"}
collection.insert_one(person_info)# 插入多个文档
person_info_list = [{"name": "Amy", "address": "上海"},{"name": "Hannah", "address": "南京"},{"name": "Joe", "address": "上海"}
]
collection.insert_many(person_info_list)

4.文档查询

使用find_one()方法查询单个文档,或者使用find()查询满足条件的多个文档。

# 查询单个文档
query = {"name": "John"}
document = collection.find_one(query)
print(document)# 查询多个文档
query = {}
documents = collection.find(query)
for document in documents:print(document)

5.更新文档

使用update_one()方法更新单个文档,或者使用update_many()更新多个文档。

# 更新单个文档
query = {"name": "John"}
new_values = {"$set": {"address": "杭州"}}
collection.update_one(query, new_values)# 更新多个文档
query = {"address": {"$regex": "上海"}}
new_values = {"$set": {"name": "Minnie"}}
collection.update_many(query, new_values)

6.删除文档

使用delete_one()方法删除单个文档,或者使用delete_many()删除多个文档。

# 删除单个文档
query = {"address": "杭州"}
collection.delete_one(query)# 删除多个文档
query = {"address": {"$regex": "^上"}}
collection.delete_many(query)

http://www.xdnf.cn/news/964693.html

相关文章:

  • 定时器任务——若依源码分析
  • Python包(Package)详解:模块的高级组织方式
  • DeviceNet转Modbus RTU,为纺织厂生产线赋能
  • uniapp的请求封装,如何避免重复提交请求
  • mysql-innoDB存储引擎事务的原理
  • ​​​​​​​未来已来:深度解读 BLE 6.0 的革命性特性与实战应用
  • SkyReels-V1:开启多模态视频生成的新纪元
  • SpringDoc集成到Springboot
  • 第1章信息化知识归纳总结补充内容
  • day52 ResNet18 CBAM
  • Canfestival的移植思想
  • EndNote 21完整安装指南:从零开始的详细步骤(附EndNote下载安装包)
  • HTML 文本省略号
  • HTML 标签 综合案例
  • 在鸿蒙HarmonyOS 5中HarmonyOS应用开发实现QQ音乐风格的播放功能
  • CppCon 2015 学习:Improving the future<T> with monads
  • MinHook 对.NET底层的 SendMessage 拦截真实案例反思
  • PHP和Node.js哪个更爽?
  • 【论文阅读】多任务学习起源类论文《Multi-Task Feature Learning》
  • MyBatis注解开发的劣势与不足
  • LeetCode--27.移除元素
  • Leetcode 3578. Count Partitions With Max-Min Difference at Most K
  • HTML 列表、表格、表单
  • Docker-containerd-CRI-CRI-O-OCI-runc
  • 【kafka】Golang实现分布式Masscan任务调度系统
  • Python 自动化临时邮箱工具,轻松接收验证码,支持调用和交互模式(支持谷歌gmail/googlemail)
  • 【C++】26. 哈希扩展1—— 位图
  • 【PhysUnits】17.5 实现常量除法(div.rs)
  • Linux上并行打包压缩工具
  • Cryosparc: Local Motion Correction注意输出颗粒尺寸