MongoDB数据库

Posted dream-huang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB数据库相关的知识,希望对你有一定的参考价值。

一、初识MongoDB

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

  • MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

它和我们使用的关系型数据库最大的区别就是约束性,可以说文件型数据库几乎不存在约束性,理论上没有主外键约束,没有存储的数据类型约束等等

关系型数据库中有一个 "" 的概念,有 "字段" 的概念,有 "数据条目" 的概念

MongoDB中也同样有以上的概念,但是名称发生了一些变化,严格意义上来说,两者的概念即为相似,但又有些出入,不过无所谓,我们就当是以上概念就好啦

接下来看一下MongoDB中存储数据的实例:

技术分享图片

  是不是感觉里面其实就是个列表,里面放着三个字典,如果你理解成了列表和字典,那么证明了你只会Python,在其他语言中它又是别的类型了,我们把这种类型的玩意儿,叫做    Json,那么你就该恍然大悟了吧,MongoDB的每个表(Collection)中存储的每条数据(Documents)都是一个一个的Json,Json中的每一个字段(Key)我们称之为:Field。就此我们引出了三个关键字,Collection也就是关系型数据库中"表"的概念,Documents就是"数据条目",Field就是"字段"

MongoDB安装部署

如果懒到不想去找安装包就用我这个吧,不过不保证版本跟得上啊。 传送门

安装中。。。。。。。

好了,安装完了,将bin目录配置好环境变量。

打开CMD,开启服务端:

技术分享图片

创建好目录之后,再试一次应该可以成功了,成功之后千万别关闭CMD窗口。

 技术分享图片

下面再打开一个一个CMD窗口,开启客户端。

技术分享图片

 

二、MongoDB之数据类型

Object  ID :Documents 自生成的 _id

String: 字符串,必须是utf-8

Boolean:布尔值,true 或者false (这里有坑哦~在我们大Python中 True False 首字母大写)

Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)

Double:浮点数 (没有float类型,所有小数都是Double)

Arrays:数组或者列表,多个值存储到一个键 (list哦,大Python中的List哦)

Object:如果你学过Python的话,那么这个概念特别好理解,就是Python中的字典,这个数据类型就是字典

Null:空数据类型 , 一个特殊的概念,None Null

Timestamp:时间戳

Date:存储当前日期或时间unix时间格式 (我们一般不用这个Date类型,时间戳可以秒杀一切时间类型)

Object ID

"_id" : ObjectId("5b151f8536409809ab2e6b26")

#"5b151f85" 代指的是时间戳,这条数据的产生时间
#"364098" 代指某台机器的机器码,存储这条数据时的机器编号
#"09ab" 代指进程ID,多进程存储数据的时候,非常有用的
#"2e6b26" 代指计数器,这里要注意的是,计数器的数字可能会出现重复,不是唯一的
#以上四种标识符拼凑成世界上唯一的ObjectID
#只要是支持MongoDB的语言,都会有一个或多个方法,对ObjectID进行转换
#可以得到以上四种信息

#注意:这个类型是不可以被JSON序列化的

 

这是MongoDB生成的类似关系型DB表主键的唯一key,具体由24个字节组成:

0-8字节是时间戳,

9-14字节的机器标识符,表示MongoDB实例所在机器的不同;

15-18字节的进程id,表示相同机器的不同MongoDB进程。

19-24字节是计数器

三、增删查改

创建数据库

  • 这里和一般的关系型数据库一样,都要先建立一个自己的数据库空间

注意点:MongoDB设计的比较随意,没有就认为你是在创建,use zhineng 是不存在的,所以MongoDB就认为你是要创建并使用

这个概念一定要记清楚哦,MongoDB中如果你使用了不存在的对象,那么就等于你在创建这个对象哦。

> use zhineng
switched to db zhineng
> db
zhineng

 

创建一张表

> db.user
zhineng.user

 

插入数据(insert     insertOne     insertMany)

  • insert   插入一条或多条数据,需要带有允许插入多条的参数,这个方法目前官方已经不推荐使用。
> db.zhineng.user.insert({"name":"dream", "age":18})
WriteResult({
"nInserted" : 1 })

 

  • insertOne  插入一条数据。
> db.zhineng.user.insertOne({"name":"dream1", "age":18})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("5bb45de8a26a4ba5d02b81e5")
}
  • insertMany   插入多条数据,无需参数控制。
> db.zhineng.user.insertMany([{"name":"dream4", "age":18},{"name":"dream5","age":18}])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("5bb45ec2a26a4ba5d02b81e7"),
                ObjectId("5bb45ec2a26a4ba5d02b81e8")
        ]
}

 

查询数据(find findOne)这里没有findMany

  • find    无条件查找:将该表(Collection)中所有的数据一次性返回,

  • find({age:18})   有条件查找返回符合条件的

> db.zhineng.user.find()
{ "_id" : ObjectId("5bb45d6ca26a4ba5d02b81e4"), "name" : "dream", "age" : 18 }
{ "_id" : ObjectId("5bb45de8a26a4ba5d02b81e5"), "name" : "dream1", "age" : 18 }
{ "_id" : ObjectId("5bb45e5fa26a4ba5d02b81e6"), "name" : "dream2", "age" : 18 }
{ "_id" : ObjectId("5bb45ec2a26a4ba5d02b81e7"), "name" : "dream4", "age" : 18 }
{ "_id" : ObjectId("5bb45ec2a26a4ba5d02b81e8"), "name" : "dream5", "age" : 18 }

 

  • findOne({age:18})  如果有多条数据符合,返回第一个。
  •    无条件返回当前Collection中的第一条数据
> db.zhineng.user.findOne({age:18})
{
        "_id" : ObjectId("5bb45d6ca26a4ba5d02b81e4"),
        "name" : "dream",
        "age" : 18
}

 

 修改数据(update updateOne updateMany),跟insert一样,不推荐update的写法

  • update    根据条件修改该条数据的内容。

  • 这里要注意的是({"条件"},{"关键字":{"修改内容"}}),其中如果条件为空,那么将会修改Collection中所有的数据。
> db.zhineng.user.update({"name":"dream"},{$set:{"age":19}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  • updateOne({"age":19},{$set:{"name":"dream"}}):根据条件修改一条数据的内容,如出现多条,只修改最高前的数据

  • updateMany({"age":19},{$set:{"name":"dream"}}):根据条件修改所有数据的内容,多条修改。

删除数据(remove) 

  • remove({}):无条件删除数据,这里要注意了,这是删除所有数据,清空Collection

  • remove({"name":"dream"}) : 条件删除name等于"dream"的所有Document

 

四、MongoDB之$关键字及$修改器

查询中常见的 等于 大于 小于 大于等于 小于等于

等于,其实就是用  :  来表示。

大于,在MongoDB中的 大于 > 号 我们用 : $gt  比如 :  "score" : { $gt : 80 } 就是 得到 "score" 大于 80 的数据

小于 : 在MongoDB中的 小于 < 号 我们用 : $lt  比如 :  "score" : { $lt : 80 } 就是 得到 "score" 小于 80 的数据

大于等于 : 在MongoDB中的 大于等于 >= 号 我们用 : $gte  比如 :  "score" : { $gte : 80 } 就是 得到 "score" 大于等于 80 的数据

小于等于 : 在MongoDB中的 小于等于 <= 号 我们用 : $lte  比如 :  "score" : { $lte : 80 } 就是 得到 "score" 小于等于 80 的数据

 

这就是MongoDB中的运算符,是不是很类似我们使用的ORM中的运算符啊,没错,最开始的时候我们就已经说了,MongoDB的操作就是很类似ORM的。

update中的修改器 $inc $set $unset $push $pull

  • $inc   在原来的数值+-运算,不存在则创建。

> db.zhineng.user.update({"age":19},{$inc:{"age":-1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  • $set  为值重新赋值,不存在则创建。
  • $unset : 用来删除Key(field)的

  • $push : 它是用来对Array (list)数据类型进行 增加 新元素的,相当于我们Python中 list.append() 方法

  • $pull : 有了$push 对Array类型进行增加,就一定有办法对其内部进行删减,$pull 就是指定删除Array中的某一个元素

  • $pop : 指定删除Array中的第一个 或 最后一个 元素,1表示最后一个,-1表示第一个。

 

五、MongoDB之 Array Object的特殊操作

Array

  • 我们用了引用下标的方法更改了数值 , "mm.1"代指的是 Array 中第2个元素。

技术分享图片

  • 混合用法:如果 mm.1 中小于2000则加 200
> db.zhineng.user.update({"name":"dream","mm.1":{"$lt":2000}},{$inc:{"mm.1":200}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

 

 

Object 字典总玩儿过吧,但是这里更像是 javascript 中的 Object 对象

  • 把dict中 a改为 10
db.zhineng.user.update({"name":"dream"},{$set:{"dict.a":10}})

 

对了就是在这个对象 打点儿 key 就可以更改数值了 , 要注意的是, 咱们用的 $set 进行修改的,那么就意味着,如果没有"dict.a"这个field的话,他会自动创建。

  • 混合用法,如果a小于20则加10
 db.zhineng.user.update({"name":"dream","dict.a":{"$lt":20}},{$inc:{"dict.a":10}})

 

 

Array + Object 的用法

{
    "_id" : ObjectId("5b17de9d44280738145722b9"),
    "name" : "user",
    "price" : [
        {
            "start" : "2018年8月1日",
            "start_time" : "08:30",
            "count" : 150
        },
        {
            "start" : "2018年8月2日",
            "start_time" : "09:30",
            "count" : 160
        },
        {
            "start" : "2018年8月3日",
            "start_time" : "10:30",
            "count" : 170
        },
        {
            "start" : "2018年8月4日",
            "start_time" : "11:30",
            "count" : 180
        }
    ]
}

 

  • count 大于 175 的field  加 15

db.user.update({"price.count":{$gt:175}},{$inc:{"price.$.count":15}})

 

解析:{"price.count":{$gt:175}}, price 明明是个 Array 啊 怎么就直接 打点儿 count 了呢 这里要知道price 打点儿 就是从内部的Object 中找到 count 小于 175 的结果

{$inc:{"price.$.count":15}} ,  这里就比较好理解了,price里面第 $ (大于175的第一个) 个元素中 count 增加 15。

六、Limit选取、SKio跳过、Sort排序。

Limit 选取 : 我要从这些 Document 中取出多少个

  • 取2 条 Document
> db.zhineng.user.find().limit(2)
{ "_id" : ObjectId("5bb45d6ca26a4ba5d02b81e4"), "name" : "dream", "mm" : [ 10, 1200, 30, 40 ], "dict" : { "a" : 20, "b" : 2, "c" : 3 } }
{ "_id" : ObjectId("5bb45de8a26a4ba5d02b81e5"), "name" : "dream1", "age" : 18 }

 

limit(2) 就是选取两条Document, 从整个Collection的第一条 Document 开始选取两条

如果我们不想从第一条Document开始选取,怎么办呢?那就要使用到skip了。

Skip 跳过 : 我要跳过多少个Document

  • 我要跳过前两个 Document 直接从第三个Document 开始

> db.zhineng.user.find().skip(2).limit(2)
{ "_id" : ObjectId("5bb45e5fa26a4ba5d02b81e6"), "name" : "dream2", "age" : 18 }
{ "_id" : ObjectId("5bb45ec2a26a4ba5d02b81e7"), "name" : "dream4", "age" : 18 }

 

Sort 排序 : 将结果按照关键字排序

  • 将find出来的Document 按照 age进行 升序 | 降序 排列
  • 1为升序、-1位降序。

db.zhineng.user.find().sort({"age":1})

重点!!!!

Sort + Skip + Limit 是有执行优先级的 他们的界别分别是 优先 Sort  其次 Skip 最后 Limt

Skip + Limit 的优先级 也是先 Skip 再 Limit

 

以上是关于MongoDB数据库的主要内容,如果未能解决你的问题,请参考以下文章

mongodb关联查询

无法在 MongoDB(猫鼬)文档中追加数组

ios - Heroku 和 MongoDb 上的自定义解析服务器错误 3080:JSON 文本没有以数组或对象开头,并且允许未设置片段的选项

mongodb snappy 压缩数据大小与存储大小

在 Spring MongoDB 的 ReplaceRoot 管道阶段使用 $mergeObjects

文档数据库:冗余数据、参考资料等(特别是 MongoDB)