MongoDB 基础

MongoDB

基础

  • 启动 & 关闭

启动

若启动时,不指定任何参数, MongoDB 会默认使用 /data/db 目录存储数据,我们可以使用 --dbpath 来指定其它的路径,比如我使用的是下面这样的命令启动的:
mongod --dbpath /Users/zcw/dev/MongoDB/db
上面这个是我的工作目录,直接将 MongoDB 的程序和数据库放在一起,我方便学习管理。

我们还可以在连接数据时指定服务器地址、端口号以及数据名等参数,比如:

mongo mongo-db.xingzhewujiang.com:30000/ahaInsight

关闭

> use admin
> db.shutdownServer()

要注意的是,这个命令只允许在本地,或是一个经过认证的客户端。

  • 运行 shell
mongo shell

启动时, shell 会打印出当前 shell 的版本号,连接到了哪个库以及一些帮助信息等,这是一个功能完备的 JavaScript 解释器,可以运行任意 JavaScript 程序,比如使用 JavaScript 标准库或者定义以及调用 JavaScript 函数等。

  • Shell 中的基本操作(在 shell 中查看查看或操作数据,会用到4个基本操作:创建、读取、更新、删除,即 CRUD 操作;)

创建
通过 db.createCollection() 函数可以先创建一个集合:

> db.createCollection("blog")
{ "ok" : 1 }

insert 可以将一个文档添加到集合中:

> post = {"title": "这是一篇文章", "content": "这是文章的内容。","date" : new Date()}

{
    "title" : "这是一篇文章",
    "content" : "这是文章的内容。",
    "date" : ISODate("2015-04-21T02:22:52.899Z")
}

这是一个有效的 MongoDB 文档,所以可以用 insert 方法将其保存到集合中。

> db.blog.insert(post)

WriteResult({ "nInserted" : 1 })

接着可以使用 find 方法查找这篇文章:

> db.blog.find()

{ "_id" : ObjectId("5535b574b705494e688e218a"), "title" : "这是一篇文章", "content" : "这是文章的内容。", "date" : ISODate("2015-04-21T02:22:52.899Z") }

可以看到我们的数据都已经完整的保存下来了,同时,MongoDB 还为我们自动生成了一个 _id 参数。

读取
find 与 findOne 方法可以用于查询集合里的文档:

> db.blog.findOne()

{
    "_id" : ObjectId("5535b574b705494e688e218a"),
    "title" : "这是一篇文章",
    "content" : "这是文章的内容。",
    "date" : ISODate("2015-04-21T02:22:52.899Z")
}

更新
使用 update 修改博客文章,它至少接受两个参数,第一个是限定条件,第二个是新文档,比如我们现在要给 post 加上评论列表:

> post.comments = []

[ ]

然后,用新版本的 post 替换标题为 《这是一篇文章》的文章:

> db.blog.update({"title":"这是一篇文章"},post)

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
    "_id" : ObjectId("5535b574b705494e688e218a"),
    "title" : "这是一篇文章",
    "content" : "这是文章的内容。",
    "date" : ISODate("2015-04-21T02:22:52.899Z"),
    "comments" : [ ]
}

可以看到,comments 已经更新到原来的那个 post 中去了。

删除
使用 remove 可以删除集合中的文档,若没有任何限定参数,它将删除集合中的所有数据,也可以像下面这样,删除标题为《这是一篇文章》的文章:

> db.blog.remove({"title":"这是一篇文章"})
WriteResult({ "nRemoved" : 1 })
> db.blog.find()
> 

除了交互式的使用 shell 外,我们还可以将命令保存在一个文件中,比如 script.js ,然后使用 mongo 命令直接执行它们,一次可以传入多个文件名,mongo shell 会依次执行传入的脚本,然后退出:

mongo script.js script1.js

如果希望指定主机和端口来运行上面的脚本,还可以这样做:

mongo --quiet host.name:30000/dbname script.js script1.js

—quiet 可以让 mongo shell不打印 MongoDB shell version... 这样的提示信息。

在交互式的命令行中,还可以使用 load() 函数加载并运行脚本:


> load("script.js")
i am a string printed by script.js

知道这个之后,我们可以把一些能用的函数保存到一个文件里面,然后再将他们加载进 shell 交互界面里面来:

创建一个名为 connectTo.js 的文件,内容如下:

/**
 * 链接到指定的数据库,然后将 db 指向这个链接
 */
var connectTo = function(port, dbname) {
    if (!port) {
        port = 27017;
    }

    if (!dbname) {
        dbname = "test"
    }

    db = connect("localhost:" + port + "/" + dbname)
    return db
}

然后我们进入 shell :


> typeof connectTo
undefined
> load("connectTo.js")
true
> typeof connectTo
function

我们可以使用脚本让能用的管理和任务自动化,比如,我们想在每一次 shell 启用时,都加载上面定义的那个函数,这个时候我们可以用到一个名为 .mongorc.js 的文件。

在自己的家目录中(不同的系统都不一样),新建一个名为 .mongorc.js 的文件,然后写入下面这些内容:

print("你好,我来自 .mongorc.js 文件")

然后,重新进入 shell:

mongo
MongoDB shell version: 3.0.2
connecting to: test
你好,我来自 .mongorc.js 文件
  • MongoDB 客户端

shell 是一个独立的 MongoDB客户端,启动时, shell 会连到 MongoDB 服务器的 test 数据库,并将数据库连接赋值给合局变量 db ,这个变量是通过 shell访问 MongoDB 的主要入口点,可以使用 db 查看当前指向哪个数据库:db

除了JavaScript语法外,MongoDB 还提供了一些语法糖,以帮助我们更好的管理数据库,比如:

> use foobar
switched to db foobar

启动时,可以让 mongo shell 不连接任何的 mongod ,可以通过 --nodb 参数:

mongo --nodb

启动之后,我们可以在需要时执行 new Mongo(hostname) 命令就可以连接到想要连接的 mongod 了:

> conn = new Mongo("host.name:30000")
connection to host.name:30000
> db = conn.getDB("dbname")
dbname

在使用 shell 的过程中,还可以随时使用 help 命令查看帮助:

help
    db.help()                    help on db methods
    db.mycoll.help()             help on collection methods
    sh.help()                    sharding helpers
    rs.help()                    replica set helpers
    help admin                   administrative help
    help connect                 connecting to a db help
    help keys                    key shortcuts
    help misc                    misc things to know
    help mr                      mapreduce

    show dbs                     show database names
    show collections             show collections in current database
    show users                   show users in current database
    show profile                 show most recent system.profile entries with time >= 1ms
    show logs                    show the accessible logger names
    show log [name]              prints out the last segment of log in memory, 'global' is default
    use <db_name>                set current database
    db.foo.find()                list objects in collection foo
    db.foo.find( { a : 1 } )     list objects in foo where a == 1
it                           result of the last line evaluated; use to further iterate
    DBQuery.shellBatchSize = x   set default number of items to display on shell
    exit                         quit the mongo shell
  • 数据类型

MongoDB 的文档与 JavaScript 中的对象相近,因而可以认为类似于 JavaScript 中的 JSON,JSON 是一种简单的数据表示方式,仅有 6种数据类型,分别为 null、bool、number、string、array 和 object。

MongoDB在保留 JSON 基本键/值对特性的基础上,添加了其它的一些数据类型:null

用于表示空值或者不存在的字段:

{
    "x" : null
}

number 数值

shell 默认使用 64位浮点型数值,对于整型值,可使用 NumberInt 类或 NumberLong 类:

{
    "pi" : 3.14,
    "x" : 3,
    "ni" : NumberInt("3"),
    "nl" : NumberLong("3")
}

string 字符串

UTF-8 类型的字符串都可以表示为字符串类型的数据:

{
    "x" : "this is a string.",
    "y" : "这是一个NB的字符串"
}

date 日期

日期被存储 为自新纪元以来经过的毫秒数,不存储时区:

{
    "x" : new Date()
}

regular expression 正则表达式

在进行查询时,我们可以直接使用正则表达式作为值,语法与 javascript 的相同:

{
    "x" : /foobar/i
}

array 数组

数据列表或数据集可以表达为数组:

{
    "a" : ["x", "y" , "z"]
}

object id 对象ID

对象ID是一个 12 字节的ID,它是文档的唯一标识:

{
    "x" : ObjectId()
}

object id 以以下方式生成:

|0|1|2|3|4|5|6|7|8|9|10|11|
|  时间戳  | 机器|PID|   计数器   |

时间戳在前,对于索引效率提高有一定的作用;同时它也带了一定的时间信息,一些驱动可以从 ObjectId 获取这些信息;
时间戳与机器码还有 PID 组合在一起,提供了秒级别的唯一性,机器码是机器主机名的散列值(hash);
PID确保了同一台主机不同进程产生的 ObjectId 的唯一性,接下来的字节
最后的计数器,确保同一台机器同一个进程在同一秒内产生的 ObjectId 是不一样的,一秒钟最多允许每个进程拥有 2563 个不同的ObjectId。
自动生成 _id

若插入文档时,没有提供 _id 键

object 内嵌文档

文档可以嵌套其它文档,被嵌套的文档作为父文档的值:

{
    "o" : {
        "name" : "child object"
    }
}

binary data 二进制数据

任意字节的字符串,它不直直接在 shell 中使用,如果要将非 utf-8 字符保存到数据库中,二进制数据是唯一的实现方式。

javascript 代码

查询和文档中可以包括做生意 JavaScript 代码:

{
    "script" : function() { /* code goes here */ }
}

timestamps 时间戳

不同于 Date 类型的时间戳值,它是一个 64位长度的值,它是:

前面的 32位为 time_t 值,(Unix 时间戳)
后32位是一个在给定的时间内的自增值

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

推荐阅读更多精彩内容