参考

https://www.bilibili/video/BV1bJ411x7mq?p=2&vd_source=1519960bcbf662e869de75526373a49f
上面黑马视频的文档1 https://zhenye-na.github.io/blog/2020/01/27/intro-to-mongodb.html
上面黑马视频的文档2 https://zhenye-na.github.io/blog/2020/02/07/advanced-mongodb.html

至少使用场景写的很好 https://www.bilibili/video/BV1kr4y1671x?p=3&vd_source=1519960bcbf662e869de75526373a49f

简介

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
“最像关系型数据库的 NoSQL 数据库”.

nosql

NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。而不是不是sql。
主要用于“关系性”不是很强的地方

文档型–和redis的区别

redis是key-value型存储
文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。


存的是json! bson就是二进制的json

使用场景

简单说来 就是 数据不规则 比如 得到硬件信息表 然后分cou 显卡 屏幕 下面有很多数据,“数据包数据”,用sql 要么建很多表 要么很大的表 要么只分大模块存json,但是json又不能查询




游戏场景 装备很多 还有各种乱七八糟的镶嵌啊 强化啊 身上的 耐久度啊之类的 用mysql很麻烦
不需要leftjoin 直接在文档中就全部查出来了

上面 电话 email 都可能有多个 所以得单独建email phone表 而文档型就没这个问题


社交场景中 比如有附近的人 位置等信息 mysql不方便

如果上面的功能用mysql也能实现 但是要求mysql使用的很好 比如索引等等 直接mongodb就不用这么高的xx。

另外 mysql建表就要很久,而且得预留很多不一定用的到的字段。

如何确定是否要用

安装

https://www.runoob/mongodb/mongodb-linux-install.html

概念解释

创建数据库

use DATABASE_NAME   

如果数据库不存在,则创建数据库,否则切换到指定数据库。

查看所有数据库用

show dbs

注意 只有db中有数据 才会被这个命令显示出来

删除数据库

db.dropDatabase()

完整示例,要先进到数据库中才能删除db

> show dbs
> use runoob
> db.dropDatabase()

集合(表)

db.createCollection(name, options)

参数说明:
name: 要创建的集合名称
options: 可选参数, 指定有关内存大小及索引的选项
如,创建固定集合 mycol,整个集合空间大小 6142800 B, 文档最大个数为 10000 个。

db.createCollection("mycol", { capped : true, autoIndexId : true, size : 
   6142800, max : 10000 } )

如果要查看已有集合,可以使用 show collectionsshow tables 命令

在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。

> db.mycol2.insert({"name" : "菜鸟教程"})
> show collections
mycol2

删除集合

db.collection.drop()

完整示例

>use mydb
switched to db mydb

>show collections
mycol
mycol2
system.indexes
runoob

>db.mycol2.drop()
true

文档

插入文档

MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:

db.COLLECTION_NAME.insert(document)

db.COLLECTION_NAME.save(document)

save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 来代替。
insert(): 若插入的数据主键已经存在,则会抛org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。

实例

> db.col.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})
> db.col.find()  #查看插入的文档
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }

我们也可以将数据定义为一个变量,然后插入

> document=({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});
> db.col.insert(document)

更新文档

MongoDB 使用 update() 和 save() 方法来更新集合中的文档。

update() 方法
update() 方法用于更新已存在的文档。语法格式如下:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

参数说明:

query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。

>db.col.insert({
    title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   # 输出信息
> db.col.find().pretty()
{
        "_id" : ObjectId("56064f89ade2f21f36b03136"),
        "title" : "MongoDB",
        "description" : "MongoDB 是一个 Nosql 数据库",
        "by" : "菜鸟教程",
        "url" : "http://www.runoob",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}

可以看到标题(title)由原来的 “MongoDB 教程” 更新为了 “MongoDB”。

以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})

删除文档

MongoDB remove() 函数是用来移除集合中的数据。

MongoDB 数据更新可以使用 update() 函数。在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确,这是一个比较好的习惯。
语法
remove() 方法的基本语法格式如下所示:

db.collection.remove(
   <query>,
   <justOne>
)

如果你的 MongoDB 是 2.6 版本以后的,语法格式如下:

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

参数说明:

query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
writeConcern :(可选)抛出异常的级别。

> db.col.find()
{ "_id" : ObjectId("56066169ade2f21f36b03137"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
{ "_id" : ObjectId("5606616dade2f21f36b03138"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
>db.col.remove({'title':'MongoDB 教程'})
WriteResult({ "nRemoved" : 2 })           # 删除了两条数据
>db.col.find()
……                                        # 没有数据

查询

普通查询

MongoDB 查询文档使用 find() 方法。

db.collection.find(query, projection)

query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

pretty() 方法以格式化的方式来显示所有文档。

> db.col.find().pretty()
{
        "_id" : ObjectId("56063f17ade2f21f36b03133"),
        "title" : "MongoDB 教程",
        "description" : "MongoDB 是一个 Nosql 数据库",
        "by" : "菜鸟教程",
        "url" : "http://www.runoob",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}

除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。

and查询

MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。

语法格式如下:

db.col.find({key1:value1, key2:value2}).pretty()

> db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()

or条件

MongoDB OR 条件语句使用了关键字 $or,语法格式如下:

>db.col.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

以下实例中,我们演示了查询键 by 值为 菜鸟教程 或键 title 值为 MongoDB 教程 的文档。

>db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

AND 和 OR 联合使用

以下实例演示了 AND 和 OR 联合使用,类似常规 SQL 语句为: ‘where likes>50 AND (by = ‘菜鸟教程’ OR title = ‘MongoDB 教程’)’

>db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]})

大于小于等条件

(>) 大于 - $gt
(<) 小于 - $lt
(>=) 大于等于 - $gte
(<= ) 小于等于 - $lte

大于操作符示例

db.col.find({likes : {$gt : 100}})

类似于SQL语句:

Select * from col where likes > 100;

指定类型查询

如果想获取 “col” 集合中 title 为 String 的数据,你可以使用以下命令:

db.col.find({"title" : {$type : 2}})  
或
db.col.find({"title" : {$type : 'string'}}) #建议用这种方式查询 

限制条数

limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
如:

> db.col.find({},{"title":1,_id:0}).limit(2)

我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。

排序

在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。

>db.COLLECTION_NAME.find().sort({KEY:1})
>db.col.find({},{"title":1,_id:0}).sort({"likes":-1})  #降序排列

索引

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。

这种扫描集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

MongoDB使用 createIndex() 方法来创建索引。

注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。

语法
createIndex()方法基本语法格式如下所示:

>db.collection.createIndex(keys, options)

语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

实例

>db.col.createIndex({"title":1})
>db.col.createIndex({"title":1,"description":-1}) #复合索引

聚合(求平均值等)

>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

其他特性

菜鸟教程,复制、分片、备份、监控、高级教程等没看

golang的使用

https://segmentfault/a/1190000041086552?sort=newest

Date类型

二,针对Date字段的操作

mongodb shell:

写入:

db.students3.insert([ { “_id” : 1, “tests” : [ 95, 92, 90 ], “lastUpdate” : ISODate(“2019-01-01T00:00:00Z”) }, { “_id” : 2, “tests” : [ 94, 88, 90 ], “lastUpdate” : ISODate(“2019-01-01T00:00:00Z”) }, { “_id” : 3, “tests” : [ 70, 75, 82 ], “lastUpdate” : ISODate(“2019-01-01T00:00:00Z”) } ]);

查询:

db.students3.find({“lastUpdate”:{$gte:new Date(‘2019-01-01’)}})

三,PHP如何像操作时间戳那样直接在DB中查询Date字段类型呢?

1,试了好多种方法:原来一直以为可以直接用date类型的串就可以直接查询,比较,然而没鸟用!!!

例如 :

$s = date(‘Y-m-d H:i:s’,strtotime(‘2020-03-11’));

$e = date(‘Y-m-d H:i:s’,strtotime(‘2020-03-12’));

w h e r e [ ′ t i m e ′ ] = [ ′ b e t w e e n ′ , [ where['time'] = ['between',[ where[time]=[between,[s,$e]]

Db::connect(‘MONGO’)->table(‘students3’)->where($where)->select();

这样是没有结构,mongo识别不了这样的时间字符串,不能像MYSQL那样可以直接比较date字段类型的。

2,用php自的什么Datetime类型的也都没用,要用mongodb类库中的 MongoDB\BSON\UTCDateTime这种转化才可以

$start= new \MongoDB\BSON\UTCDateTime(strtotime(“2020-03-11 00:40:34”)*1000);
$end = new \MongoDB\BSON\UTCDateTime(strtotime(“2020-03-12 00:29:55”)*1000);
w h e r e [ ′ c r e a t e t i m e ′ ] = [ ′ b e t w e e n ′ , [ where['create_time'] = ['between',[ where[createtime]=[between,[start,$end]];
c o u n t = D b : : c o n n e c t ( ′ M O N G O ′ ) − > t a b l e ( ′ s t u d e n t s 3 ′ ) − > w h e r e ( count = Db::connect('MONGO')->table('students3')->where( count=Db::connect(MONGO)>table(students3)>where(where)->count();

四,总结,之前没用过mongodb,纠结尝试了好久才可以正常操作Date类型的字段。

更多推荐

MongoDB教程笔记