MongoDB

1. 基本介绍

1.1 存储结构

描述 MongoDB MySQL
数据库 database database
集合/表 collection table
文档/行 document row
字段属性/列 field column
表关联 不支持 join
主键 primary key primary key

1.2 文档关系

  • 引用
    {
        _id:"joe",
        name:"Joe Bookreader"
    }
    {
        patron_id:"joe",
        street:"123 Fake Street",
        city:"Faketon",
        state:"MA",
        zip:"2345"
    }
  • 嵌入
    {
        _id:"joe",
        name:"Joe Bookreader",
        address:{
            street:"123 Fake Street",
            city:"Faketon",
            state:nMAnz
            zip:T2345"
        }
    }
    {
        _id:"joe",
        name:"Joe Bookreader",
        addresses:[
            {
                street:"123 Fake Streetn,
                city:"Faketon",
                state:"MA",
                zip:"12345"
            },
            {
                street:"l Some Other Street",
                city:"Boston",
                state:"MA",
                zip:"12345"
            }
        ]
    }

1.3 BSON数据类型

类型 描述示例
NULL 表示空值或者不存在的字段,{"x":null}
Boolean 布尔型有 true 和 false,{"x":true}
Number 数值:客户端默认使用 64 位浮点型数值。{"x":3.14} 或 {"x":3}。对于整型值,包括 NumberInt(4 字节符号整数)或 NumberLong(8 字节符号整数),用户可以指定数值类型,{"x":NumberInt("3")}
String 字符串:BSON 字符串是 UTF-8,{"x":"中文"}
Regular Expression 正则表达式:语法与JavaScript 的正则表达式相同,{"x":[cba]}
Array 数组:使用"[]"表示,{"x":["a", "b", "c"]}
Object 内嵌文档:文档的值是嵌套文档,{"a":{"b":3}}
ObjectId 对象 id:对象 id 是一个 12 字节的字符串,是文档的唯一标识,{"x":objectId()}
BinaryData 二进制数据:二进制数据是一个任意字节的字符串。它不能直接在 Shell 中使用。如果要将非 UTF-8 字符保存到数据库中,二进制数据是唯一的方式
JavaScript 代码:查询和文档中可以包括任何 JavaScript 代码,{"x":function(){/.../}}
Date 日期:{"x":new Date()}
Timestamp 时间戳:var a = new Timestamp()

2. 安装

3. 语法

3.1 数据库

3.1.1 命名规则

序号 注意事项
1 不能是空串
2 不得含有 /、\、?、$、空格、空字符等,基本只能使用 ASCII 中的字母和数字
3 区分大小写,建议全部小写
4 名称最多为 64 字节
5 不得使用保留的数据库名,如:admin、local、config

3.1.2 保留数据库

库名 作用
admin 权限数据库,添加用户到该数据库中,该用户会自动继承数据库的所有权限
local 数据库中的数据永远不会被复制
config 分片时,config 数据库在内部使用,保存分子信息
test 默认数据库,可以用来做各种测试等

3.1.3 常用脚本

功能 脚本
使用及查看数据库 use test
展示所有数据库 show dbs
统计数据库信息 db. stats ()
删除数据库 db.dropDatabase ()
查看所有集合名称 db.getCollectionNames ()

3.2 集合

3.2.1 命名规则

序号 注意事项
1 集合名不能是空串
2 不能含有空字符 \0
3 不能以“system.”开头,这是系统集合保留的前缀
4 集合名不能含保留字符“$”

3.2.2 常用脚本

  • 创建集合【显式】

db.createCollection(name, options)

name:要创建的集合名称

options:指定内存大小和索引,详见下面表格:

参数 类型 描述
capped Boolean (可选)如果为 true,则启用封闭的集合。上限集合是固定大小的集合,它在达到其最大时自动覆盖其最旧的条目。如果指定 true,则还需要指定 size 参数
size 数字 (可选)指定上限集合的最大大小(以字节为单位)。如果 capped 为 true,那么还需要指定次字段的值
max 数字 (可选)指定上限集合中允许的最大文档数

示例:db.createCollection("testcollection", {capped:true,size:6142800,max:10000 })

  • 创建集合【隐式】

db.testdb.insert( {"testcollection":"123"} )

当插入文档时,集合不存在,则MongoDB会隐式的自动创建集合。

  • 其他常用脚本
功能 脚本
查看集合详细信息 show collections
重命名集合 renamecollection()
删除集合 db.testcollection.drop()

3.2 文档

注意:文档键值对有序,且严格区分键值对的数据类型及大小写

3.2.1 数据插入

方法:insert()、insertOne()、insertMany()

语法:

db.collection.insert(
    <document or array of documents>,
    {
    writeConcern:<document>,    //可选字段
    ordered:<boolean>    //可选字段
    }
)
  • <document or array of documents> 参数表示可设置插入一条或多条文档。
  • writeConcern:<document> 参数表示自定义写出错的级别,是一种出错捕捉机制。
  • ordered:<boolean> 是可选的,默认为 true。
    • 如果为 true,在数组中执行文档的有序插入,并且如果其中一个文档发生错误,MongoDB 将返回而不处理数组中的其余文档;
    • 如果为 false,则执行无序插入,若其中一个文档发生错误,则忽略错误,继续处理数组中的其余文档。

示例:

testdb.testcollection.insert({name:"andy",age:15})
testdb.testcollection.insert({_id:10, name:"andy",age:15})
testdb.testcollection.insert(
    [
        { _id:11, name:"jack", age:50, address:"test address" },
        { name:"rose", age:20 },
        { name:"kevin", age:25 }
    ],
    {ordered:true}
)

// 变量方式插入
document=({_id:10, name:"andy",age:15})
> db.test.insert(document)

3.2.2 更新数据

3.2.2.1 update

语法:

db.collection.update(
    <query>,
    <update>,
    {
        upsert,
        multi,
        writeConcern,
        collation
    }
)
  • <query>:参数设置查询条件。

  • <update>:为更新操作符。

  • upsert:为布尔型可选项,表示如果不存在 update 的记录,是否插入这个新的文档。true 为插入;默认为 false,不插入。

  • multi:也是布尔型可选项,默认是 false,只更新找到的第一条记录。如果为 true,则把按条件查询出来的记录全部更新。

  • writeConcem:表示出错级别。

  • collation:指定语言。

示例:

// 将名字为jack的年龄设置为50岁
db.test.update(
{
    name:"jack"
},
{
    $set:{age:50}
}
    
    
db.createCollection ("person", {collation:{locale:"zh" }})    //创建集合并指定语言
db.person.insert ({name:"张三"})
db.person.insert ({name:"李四"})
db.person.insert ({name:"王五"})
db.person.insert ({name:"马六"})
db.person.insert ({name:"张七"})
db.person.find().sort({name:1}) //查询并排序
//查询返回结果
{ "_id":Objectld ("586b995d0cec8d86881cffae") , "name":"李四" }
{ "_id":Objectld ("586b995d0cec8d8 6881cffb0") , "name":"马六" }.
{ "_id":Objectld ("586b995d0cec8d86881cffaf"), "name":"王五" }
{ "_id":Objectld ("586b995d0cec8d86881cffb1"), "name":"张七" }
{ "_id":Objectld ("586b995d0cec8d86881cffad"), "name":"张三" }    

3.2.2.2 save

db.collection.save (obj)

如果存在与obj的_id相同的数据则替换数据,如果不存在则插入数据

3.2.3 删除数据

3.2.3.1 remove

永久删除MongoDB集合中的数据

  • 语法

    db.collection.remove(
        <query>,
        {
            justOne:<boolean>, writeConcern:<document>
        }
    )
    
    • query:必选项,是设置删除的文档的条件。
    • justOne:布尔型的可选项,默认为false,删除符合条件的所有文档,如果设为 true,则只删除一个文档。
    • writeConcem:可选项,设置抛出异常的级别。
  • 示例

    db.test.remove({'title':'MongoDB'})
    
    db.test.remove(
        {
            age:{$gt:3}
        }
    )
    

3.2.3.2 delete

官方推荐使用deleteOne 和 deleteMany方法删除文档,格式如下

// 删除集合下所有的文档
db.collection.deleteMany ({})

// 删除年龄为20岁的所有文档
db.collection.deleteMany ({ age:20 })

// 删除年龄为20岁的第一个文档
db.collection.deleteOne ({ age:20 })

3.2.4 查询数据

3.2.4.1 语法

db.collection.find(query, projection)

  • query 为可选项,设置查询操作符指定查询条件;
  • projection 也为可选项,表示使用投影操作符指定返回的字段,如果忽略此选项则返回所有字段。

格式化显示:db.test.find().pretty()

3.2.4.2 查询条件

操作符 格式 示例 与 RDBMS where 语句比较
等于(=) {key:{value}} db.test.find( {age:24} ) where price = 24
大于(>) {key:{$gt:value}} db.test.find( {age:{$gt:24}} ) where price > 24
小于(<) {key:{$lt:value}} db.test.find( {age:{$lt:24}} ) where price < 24
大于等于(>=) {key:{$gte:value}} db.test.find( {age:{$gte:24}} ) where price >= 24
小于等于(<=) {key:{$lte:value}} db.test.find( {age:{$lte:24}} ) where price <= 24
不等于(!=) {key:{$ne:value}} db.test.find( {age:{$ne:24}} ) where price != 24
与(and) {key01:value01, key02:value02, ...} db.test.find( {name:"jack", price:24} ) where name = "jack" and price = 24
或(or) {$or:[{key01:value01}, {key02:value02}, ...]} db.test.find( {$or:[{name:"jack"},{price:24}]} ) where name = "jack" or price = 24

特定语法:

// 不仅会查询到年龄为空的,也会匹配到所有不包含该键值的文档
db.test.find({age:null})

// 查询数组
db.test.find(
    {
        emails:['aaa@163.com', 'bbb@163.com']
    }
)

// 查询size=2的数组
db.test.find(
    {
        emails:{$size:2}
    }
)

// 查询数组包含某个值
db.test.find(
    {
        emails: "aaa@163.com"
    }
)

// 现在查询结果个数
db.test.find().limit(3)


// 跳过指定数量的文档
db.test.find().skip(1)

// 对结果排序 1升序 -1降序
db.test.find().sort({"age" : 1})

// 正则表达式匹配
db.test.find({age:{$regex:2*}})

3.2.4.3 游标

使用find行数可以返回游标

方法名 作用
hasNext 判断是否有更多的文档
next 用来获取下一条文档
toArray 将查询结构放到数组中
count 查询的结果为文档的总数量
limit 限制查询结果返回数量
skip 跳过指定数目的文档
sort 对查询结果进行排序
objsLeftlnBatch 查看当前批次剩余的未被迭代的文档数量
addOption 为游标设置辅助选项,修改游标的默认行为
hint 为查询强制使用指定索引
explain 用于获取查询执行过程报告
snapshot 对查询结果使用快照

注意事项:

  1. 当调用 find() 函数时,并不立即查询数据库,而是等真正开始获取结果时才发送查询请求。

  2. 游标对象的每个方法几乎都会返回游标对象本身,这样可以方便进行链式函数的调用。

  3. 在 MongoDB Shell 中使用游标输出文档包含两种情况,如果不将 find() 函数返回的游标赋值给一个局部变量进行保存,在默认情况下游标会自动迭代 20 次。如果将 find() 函数返回的游标赋值给一个局部变量,则可以使用游标对象提供的函数进行手动迭代。

  4. 使用清空后的游标,进行迭代输出时,显示的内容为空。

游标被销毁:

  • 客户端保存的游标变量不在作用域内。
  • 游标遍历完成或者客户端主动发送终止消息。
  • 在服务器端 10 分钟内未对游标进行操作。

示例:

var cursor = db.test.find()
while (cursor.hasNext()){
    var doc = cursor.next();
    print(doc.name);
    print(doc);
    printjson(doc);
}

3.2.5 索引

3.2.5.1 创建索引

索引类型 说明 语法 排序
单键索引 支持文档集合中任何字段的索引 db.collection.createlndex({key:1})
//1 为升序,-1 为降序
索引键的排序顺序无关紧要
复合索引 支持复合索引,包含多个字段 db.records.createIndex ({"key1": 1,key2": 1 }) 需要注意索引顺序问题,会导致查询结果不一致
多键值索引 为包含数组的字段建立索引,
MongoDB 会为数组中的每个元素创建索引键。
db.collecttion.createlndex({key:1}) 集合中包含多个待索引字段是数组,则无法创建复合多键索引。
地理索引
全文索引 支持对字符串内容的文本搜索查询,但检索时间较长 db.collection.createIndex ({ key: "text" })
散列索引 按照某个字段的散列值来建立索引 db.collection.createlndex( { _id : "hashed" }) 不支持范围查询,散列索引会将浮点数截断为64位整数

稀疏索引 db.collection.createlndex ({"key":1},{sparse:true})

  • 只检索包含具有索引字段的文档,即使索引字段包含空值,检索时也会跳过所有缺少索引字段的文档
  • 非稀疏索引包含集合中的所有文档,存储不包含索引字段的文档的空值。

唯一索引 db.collection.createlndex ({"key":1},{unique:true})

过期索引 db.collection.createlndex({"key":1},{expireAfterSeconds:3600})

3.2.5.2 索引操作

功能 脚本
查看集合的所有索引 db.collection.getIndexes()
删除索引 // 删除特定索引 db.collection.dropIndex({"key":1})
// 删除所有索引 db.collection.dropIndexes()
修改索引 如果需要修改索引,则需要删除现有索引后重新创建索引

3.2.5 聚合查询

MongoDB提供了三种执行聚合的方法:

  • 聚合管道
  • map-reduce
  • 单一目标聚合方法

4. 分布式部署

[TODO-LIST]

创建索引
地理索引

聚合查询
http://c.biancheng.net/view/6563.html

安装
分布式部署
http://c.biancheng.net/view/6567.html

可视化工具Robomongo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容