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

mongosh

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


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

mongod --config "C:\Program Files\MongoDB\Server\7.0\mongod.cfg"

检查mongodb服务状态

services.msc

linux mongodb4.0.5配置安装

#下载
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 指定配置⽂件

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

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

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

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


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

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

数据库与集合的基础操作


  #查看数据库
  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.同⼀个集合中不同数据字段结构可以不⼀样


指定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
基于具体的值进⾏运算

 #基于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:"客服"}] })


排序与分页

db.emp.find().sort({dep:1,salary:-1}).skip(6).limit(3)

基于复合属性查找

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

基于数组查询


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"]}, 
 ])


# 与嵌套查询一样,必须是所有的值 并且顺序一至
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"]}})

数组嵌套查询

{  
    "_id": ObjectId("..."),  
    "subjects": [  
        {  
            "name": "redis",  
            "hour": 12  
        },  
        {  
            "name": "mysql",  
            "hour": 120  
        },  
        {  
            "name": "mongodb",  
            "hour": 8  
        }  
    ]  
}

 #基础查询 ,必须查询全部,且顺序一致
 #这个查询会匹配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})

修改与删除

修改

db..update(条件,{设置值},false,false)

删除字段

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 字段的示例:


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 数组的第一个元素,你可以这样做:

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

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

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

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

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


{  
    "_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}}}) 命令后,文档将被更新为:


{  
    "_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}})

相关推荐

  1. 001 mongodb

    2024-05-26 01:38:36       12 阅读
  2. <span style='color:red;'>mongoDB</span>

    mongoDB

    2024-05-26 01:38:36      50 阅读
  3. <span style='color:red;'>MongoDB</span>

    MongoDB

    2024-05-26 01:38:36      29 阅读
  4. <span style='color:red;'>MongoDB</span>

    MongoDB

    2024-05-26 01:38:36      40 阅读
  5. MongoDB

    2024-05-26 01:38:36       29 阅读
  6. mongodb

    2024-05-26 01:38:36       28 阅读
  7. <span style='color:red;'>MongoDB</span>

    MongoDB

    2024-05-26 01:38:36      25 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-26 01:38:36       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-26 01:38:36       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-26 01:38:36       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-26 01:38:36       20 阅读

热门阅读

  1. QT--splitter的使用

    2024-05-26 01:38:36       11 阅读
  2. 39. 组合总和 - 力扣(LeetCode)

    2024-05-26 01:38:36       11 阅读
  3. 169. 多数元素

    2024-05-26 01:38:36       9 阅读
  4. 15、Go Gin常见响应返回详解

    2024-05-26 01:38:36       11 阅读
  5. 掌握C++回调:按值捕获、按引用捕获与弱引用

    2024-05-26 01:38:36       12 阅读
  6. 【数据结构与算法 | 基础篇】数组模拟栈

    2024-05-26 01:38:36       12 阅读
  7. 银发经济:老龄化社会中的机遇与挑战

    2024-05-26 01:38:36       10 阅读
  8. 基于Amazon Cognito的安全登录与资源访问

    2024-05-26 01:38:36       11 阅读