001 mongodb

文章目录

NoSql

分类

键值(Key-Value)存储数据库

这类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下。举例:Tokyo Cabinet/Tyrant,Redis,Voldemort,Oracle BDB

列存储数据库

这部分数据库通常是用来应付分布式存储的海量数据。键仍然存在,但是它们的特定是指向了多个列。这些列是由列家族来安排的。如:Cassandra,HBase,Riak

文档型数据库

文档型数据库的灵感是来自于Lotus Notes办公软件,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB,MongoDb。国内也有文档型数据库SequoiaDB,已经开源。

图形(Graph)数据库

图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J,InfoGrid,Infinite Graph

NoSql的应用场景

1.数据模型比较简单

2.需要灵活性更强的IT系统

3.对数据库性能要求较高

4.不需要高度的数据一致性

MongoDb

笛卡尔集

在探讨MySQL和MongoDB在处理电影表、影评表、影评评论表时为何一个可能出现笛卡尔集而另一个不会的问题时,我们首先要理解这两种数据库的本质区别。

MySQL(关系型数据库)

数据结构:MySQL是关系型数据库,数据以表格形式严格定义,并通过SQL语言进行查询。表与表之间存在明确的关系,通常通过主键和外键来维护。

笛卡尔集问题:当在MySQL中进行多表连接查询时,如果没有明确指定连接条件(如使用WHERE子句或JOIN条件),系统会返回所有可能的组合,即笛卡尔集。这是因为关系型数据库通过表之间的关联来组织和查询数据。

示例:假设有电影表和影评表,如果没有正确指定连接条件,查询结果将是两部表中所有记录的组合,这通常会导致数据量巨大且不包含有效信息的结果集。

MongoDB(文档型数据库)

数据结构:MongoDB是文档型数据库,使用BSON(Binary JSON)格式存储数据。它不依赖于固定的表结构,而是存储自包含的文档。每个文档可以有不同的字段和结构。

避免笛卡尔集:在MongoDB中,数据通常以嵌套文档或数组的形式组织,这意味着相关信息被整合在同一个文档中。由于不存在严格的表结构,因此在进行查询时,不需要像关系型数据库那样进行表连接操作。这种数据模型自然地避免了笛卡尔集的问题。

示例:在MongoDB中,一部电影的信息和它的影评可以被组织在同一个文档中,或者通过某种方式关联(如使用电影ID作为影评文档中的一个字段)。这样,在查询时就不会产生无关的组合。

总结

MySQL等关系型数据库在处理多表查询时需要明确指定连接条件,否则会产生笛卡尔集。

MongoDB的文档型数据模型使得相关数据可以自然地组织在一起,从而避免了笛卡尔集的问题。

在设计数据库和编写查询时,了解这两种数据库的不同特性和最佳实践是非常重要的。

综上所述,虽然MySQL和MongoDB都可以用来存储和查询电影、影评等相关信息,但由于它们的数据模型和查询方式的不同,MongoDB在处理这类数据时不会遇到MySQL中可能出现的笛卡尔集问题。

mysql与mongodb逻辑结构对比

数据库对应数据库

表对应集合

数据行对应文档

字段对应字段

外键对应嵌套文档

关系型数据库 MongoDb
database(数据库) database(数据库)
table (表) collection( 集合)
row( ⾏) document( BSON ⽂档)
column (列) field (字段)
index(唯⼀索引、主键索引) index (全⽂索引)
join (主外键关联) embedded Document (嵌套⽂档)
primary key(指定1⾄N个列做主键) primary key (指定_id field做为主键)
aggreation(groupy) aggreation (pipeline mapReduce)

mongodb社区版下载地址

https://www.mongodb.com/download-center/community

windows mongodb7.0配置安装

mongoshell下载地址

https://www.mongodb.com/try/download/shell

powershell 复制代码
mongosh

windows下创建名为mongod.cfg的配置文件

powershell 复制代码
systemLog:
    destination: file
    path: C:\Program Files\MongoDB\Server\7.0\log\mongod.log
    logAppend: true
storage:
    dbPath: C:\Program Files\MongoDB\Server\7.0\data
net:
    bindIp: 127.0.0.1
    port: 27017

运行mongodb

powershell 复制代码
mongod --config "C:\Program Files\MongoDB\Server\7.0\mongod.cfg"

检查mongodb服务状态

powershell 复制代码
services.msc

linux mongodb4.0.5配置安装

powershell 复制代码
#下载
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.5.tgz 
# 解压
tar -zxvf mongodb-linux-x86_64-4.0.5.tgz

#创建数据库目录
mkdir -p /data/mongo
 # 启动mongo
./bin/mongod --dbpath=/data/mongo/

常规参数

参数 说明
dbpath 数据库⽬录,默认/data/db
bind_ip 监听IP地址,默认全部可以访问
port 监听的端⼝,默认27017
logpath ⽇志路径
logappend 是否追加⽇志
auth 是否开启⽤户密码登陆
fork 是否已后台启动的⽅式登陆
config 指定配置⽂件

配置文件示例和以配置文件方式启动

powershell 复制代码
vim mongo.conf
powershell 复制代码
dbpath=/data/mongo/ 
port=27017
bind_ip=0.0.0.0
fork=true 
logpath = /data/mongo/mongodb.log
logappend = true 
auth=false
powershell 复制代码
./bin/mongod -f mongo.conf

客户端shell的使用及参数说明

powershell 复制代码
#启动客户端 连接 本机的地的默认端口
./bin/mongo 
# 指定IP和端口
./bin/mongo --host=127.0.0.1 --port=27017

mongo shell 是⼀个js 控台,可以执⾏js 相关运算

powershell 复制代码
db.createUser({ user: "root", pwd: "123456", roles: [{ role: "dbOwner", db: "commentDB" }] });

数据库与集合的基础操作

powershell 复制代码
  #查看数据库
  show dbs; 
  #切换数据库
  use dd; 
  #创建数据库与集合,在插入数据时会自动 创建数据库与集和
  db.self.insertOne({name:"dd",sex:"man"}); 
  #查看集合
  show tables; 
  show collections; 
  #删除集合
  db.self.drop(); 
  #删除数据库
  db.dropDatabase()

mongodb数据类型

字符串 整型 布尔 浮点型 日期类型

Date():日期类型的字符串

new Date():日期类型

数据的新增

关于Mongodb数据插⼊的说明

1.数据库的新增不需要序先设计模型结构,插⼊数据时会⾃动创建。

2.同⼀个集合中不同数据字段结构可以不⼀样

powershell 复制代码
指定ID 
 db.self.insert([ 
  {_id:1,name:"dd",sex:"man",age:1}, 
  {_id:2,name:"dd",sex:"women",birthday:new Date("1999-11-    
11")}

数据的查询

概要:

a. 基于条件的基础查询

b. and、or、in、gt、gte、lt、$lte 运算符

c. 基于 sort skip limit ⽅法实现排序与分⻚

d. 嵌套查询

e. 数组查询

f. 数组嵌套查询

逻辑运算:and、or

其值为多个逻辑的组合运算,后⾯跟中括号,中括号包括多个⼤括号。

值运算:in、gt、gte、lt、$lte $all

基于具体的值进⾏运算

powershell 复制代码
 #基于ID查找
db.emp.find({_id:001})
 #基于属性查找
db.emp.find({"name":"dd"})
 # && 运算 与大于 运算
db.emp.find({"job":"程序员","salary":{$gt:8000}})
 # in 运算
db.emp.find({"job":{$in:["程序员","客服"]}})
 # or 运算
db.emp.find({$or:[{job:"程序员"  },{job:"客服"}] })

排序与分页

powershell 复制代码
db.emp.find().sort({dep:1,salary:-1}).skip(6).limit(3)

基于复合属性查找

powershell 复制代码
 基于复合属性查找 时必须包含其所有的值 并且顺序一致
 db.student.find({grade:{math:87,english:85,physics:90} }) 
 #基于复合属性当中的指定值 查找。注:名称必须用双引号
 db.student.find({"grade.math":87}); 
 db.student.find({"grade.math":{"$gt":80}});

基于数组查询

powershell 复制代码
db.subject.insertMany([ 
 {_id:"001",name:"张三",subjects:["math","english","physics"]}, 
 {_id:"002",name:"李四",subjects:["math","english"]}, 
 {_id:"003",name:"王五",subjects:["chemistry","biology","medicine"]}, 
 {_id:"004",name:"王三",subjects:["languistics","literature","sociology"]}, 
 ])
powershell 复制代码
# 与嵌套查询一样,必须是所有的值 并且顺序一至
db.subject.find({subjects:["math","english","physics"]}) 
# $all 匹配数组中包含该两项的值。注:顺序不作要求
db.subject.find({subjects:{"$all": ["math","english"]}}) 
注:
# 简化数组查询
db.subject.find({subjects:"math"}) 
# 简化数组查询 ,匹配数组中存在任意一值。与$all相对应
db.subject.find({subjects:{$in: ["math","english"]}})

数组嵌套查询

powershell 复制代码
{  
    "_id": ObjectId("..."),  
    "subjects": [  
        {  
            "name": "redis",  
            "hour": 12  
        },  
        {  
            "name": "mysql",  
            "hour": 120  
        },  
        {  
            "name": "mongodb",  
            "hour": 8  
        }  
    ]  
}
powershell 复制代码
 #基础查询 ,必须查询全部,且顺序一致
 #这个查询会匹配subjects数组中有一个对象其name为"redis"且hour为12的文档
 #上面的文档满足这个条件。
 db.subject2.find({subjects:{name:"redis",hour:12} }) 
 
 #这个查询会匹配subjects数组的第一个元素的hour字段大于12的文档 
 #上面的文档不满足这个条件,但如果您调整数组元素的顺序,将hour大于12的对象放在第一个位置,它就会满足这个条件。注意,这个查询是依赖于数组元素的顺序的
 db.subject2.find({"subjects.0.hour":{$gt:12}}) 
 
 #这个查询会匹配subjects数组中有任何一个对象的hour字段大于12的文档。上面的文档满足这个条件,因为mysql的课时是120。 
 db.subject2.find({"subjects.hour":{$gt:12}}) 
 
 # $elemMatch 元素匹配,指定属性满足,且不要求顺序一致
 #这个查询使用$elemMatch操作符来匹配subjects数组中有一个对象其name为"redis"且hour为12的文档。上面的文档满足这个条件。
 db.subject2.find({subjects:{$elemMatch:{name:"redis",hour:12}}}) 
 
 # 数组中任意元素匹配 不限定在同一个对象当中
 #这个查询会匹配subjects数组中有对象的name为"mysql"且有其他对象的hour为120的文档。注意,这两个条件不需要在同一个对象上满足。上面的文档满足这个条件。
 db.subject2.find({"subjects.name":"mysql","subjects.hour":120})

修改与删除

修改

powershell 复制代码
db.表.update(条件,{设置值},false,false)

删除字段

powershell 复制代码
db.subjects2.update({"_id":"001"},{$unset:{"subjects":1}})

在MongoDB中,_id 字段通常是一个 ObjectId 类型,而不是一个简单的字符串如 "001"。如果你确实有一个文档的 _id 字段是字符串 "001",那么这条命令是可以正常工作的。不过,通常情况下,_id 是一个 ObjectId 的实例。

解析该命令:

db.subjects2.update(...): 这表示你要更新 subjects2 这个集合中的文档。

{"_id":"001"}: 这是查询条件,表示你要更新 _id 字段值为 "001" 的文档。如果你的 _id 是 ObjectId 类型,你需要确保这里的值与实际的 ObjectId 字符串相匹配。

{unset:{"subjects":1}}: 这是更新的操作。unset 是 MongoDB 的一个更新操作符,用于从文档中移除指定的字段。在这里,它试图从匹配的文档中移除 subjects 字段。

所以,这条命令的作用是:

在 subjects2 集合中,找到 _id 为 "001" 的文档(或者是一个具体的 ObjectId 字符串,如果你的 _id 是这种类型)。

从该文档中移除 subjects 字段及其值。

如果 _id 字段实际上是 ObjectId 类型,并且你想要根据一个具体的 ObjectId 来更新文档,你需要将命令修改为类似于以下内容(假设你的 ObjectId 是 ObjectId("507f191e810c19729de860ea")):

javascript

db.subjects2.update({"_id": ObjectId("507f191e810c19729de860ea")}, {$unset: {"subjects": ""}})

注意,在 $unset 中,字段名的值可以是空字符串 "" 或者数字 1,两者在这里的效果是相同的。都是指示 MongoDB 移除该字段。在最新的 MongoDB 版本中,推荐使用空字符串 "" 作为\ $unset 的值。

如果你的 _id 确实是一个简单的字符串,比如 "001",并且你想要移除 subjects 字段,那么你提供的命令就是正确的。

向数组添加

$set

如果你想使用$set 操作符来更新 subject2 集合中的文档,你需要注意 $set 和 addToSet 在功能上的区别。addToSet 用于向数组添加一个新元素,但仅当该元素不在数组中时才添加。而 set 操作符用于设置指定字段的值,如果字段不存在,set 将创建一个新字段,使用 $set 不会检查数组中是否已经存在相同的元素。

如果你确定要使用 $set 来更新 subjects 字段,并且你知道你想要设置的确切数组结构,你可以这样做。但是,请注意,这将直接替换 subjects 数组的当前内容,而不是向数组中添加一个新元素。

以下是如何使用 $set 来更新 subjects 字段的示例:

powershell 复制代码
db.subject2.update(  
    {id: "002"},  
    {$set: {subjects: [{name: "redis", hour: 30}, {name: "dubbo", hour: 50}, {name: "mongodb", hour: 40}]}}  
)

在这个例子中,subjects 数组被设置为一个新的数组,其中包含三个对象。如果 id 为 "002" 的文档原先有其他 subjects,它们将被这个新数组完全替换。

如果你只是想用 $set 添加或修改数组中的特定元素,而不是替换整个数组,你需要指定数组索引。例如,如果你想设置 subjects 数组的第一个元素,你可以这样做:

powershell 复制代码
db.subject2.update(  
    {id: "002"},  
    {$set: {"subjects.0": {name: "dubbo", hour: 50}}}  
)

这将把 id 为 "002" 的文档的 subjects 数组的第一个元素设置为 {name: "dubbo", hour: 50}。如果数组索引超出当前数组长度,MongoDB 将不会执行任何操作。

请注意,这种方法需要你知道你想要更新的数组元素的确切索引,而且它会替换指定索引处的元素,而不是添加一个新元素。如果你不确定数组的结构或长度,使用 $addToSet 通常更安全,因为它会确保不会添加重复的元素。

$addToSet
powershell 复制代码
db.subject2.update({id:"002"},{$addToSet:{subjects: {name:"dubbo",hour:50}}})

这条命令的意图是向id为"002"的文档的subjects数组中添加一个新的课程对象,但仅当这个课程对象在数组中尚不存在时。

powershell 复制代码
{  
    "_id": ObjectId("..."),  
    "id": "002",  
    "subjects": [  
        {  
            "name": "redis",  
            "hour": 30  
        },  
        {  
            "name": "mongodb",  
            "hour": 40  
        }  
        // 注意,此时还没有 {name:"dubbo",hour:50} 这个对象  
    ]  
}

在执行了 db.subject2.update({id:"002"},{$addToSet:{subjects: {name:"dubbo",hour:50}}}) 命令后,文档将被更新为:

powershell 复制代码
{  
    "_id": ObjectId("..."),  
    "id": "002",  
    "subjects": [  
        {  
            "name": "redis",  
            "hour": 30  
        },  
        {  
            "name": "mongodb",  
            "hour": 40  
        },  
        {  
            "name": "dubbo",  
            "hour": 50  
        }  
        // {name:"dubbo",hour:50} 已经被添加到 subjects 数组中  
    ]  
}
$push不判断重复

$pull删除

$pop删除

$elemMatch

只会更新第一条

db.emp.update({"dep":"技术部"},{$inc:{salary:100}})

更新所有 匹配的条件

db.emp.updateMany({"dep":"技术部"},{$inc:{salary:100}})

相关推荐
云计算DevOps-韩老师8 分钟前
【网络云计算】2024第52周-每日【2024/12/26】小测-理论&实操-备份MySQL数据库并发送邮件-解析
linux·开发语言·网络·数据库·mysql·云计算·perl
2401_8504108319 分钟前
redis的持久化
数据库·redis·bootstrap
如雨随行202021 分钟前
Mysql事务
数据库·mysql·oracle
未来并未来1 小时前
深入解析MVCC中Undo Log版本底层存储读取逻辑
java·数据库·mysql
菜还不练就废了2 小时前
Java期末复习JDBC|网课笔记+校课总结
java·开发语言·数据库
BabyFish132 小时前
Oracle复合索引规则指南
数据库·oracle·索引·复合索引
i易2 小时前
C++ 运算符重载
java·开发语言·数据库
drebander2 小时前
SQL 实战:日期与时间函数 – 统计数据的时间跨度与趋势
linux·数据库·sql
王声声2 小时前
Mysql数据库中,监测某张表中某字段的修改情况(被哪个ip所修改、新老值)
数据库·tcp/ip·mysql
正在绘制中2 小时前
Java重要面试名词整理(六):MongoDB
java·mongodb·面试