您好,欢迎来到99网。
搜索
您的当前位置:首页mongodb教程1月11号更新

mongodb教程1月11号更新

来源:99网
 mongodb教程 第一讲

MySQL是关系型数据库中的明星,MongoDB是文档型数据库中的翘楚。 我们介绍一下两者的区别

mongodb与mysql命令对比

传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。

MySQL mysqld mysql mysqldump mysql mysqldump source grant * privileges on *.* to … show databases Show tables Show slave status Create table users(a int, b int) mongod mongo mongodump mongorestore db.repairDatabase() mongoexport mongoimport Db.addUser() Db.auth() show dbs Show collections Rs.status MongoDB 说明 服务器守护进程 客户端工具 逻辑备份工具 逻辑恢复工具 修复数据库 数据导出工具 数据导入工具 新建用户并权限 显示库列表 显示表列表 查询主从状态 db.createCollection(\"mycoll\创建表 {capped:true, size:100000}) 另:可隐式创建表。 ON db.users.ensureIndex({name:1}) ON db.users.ensureIndex({name:1,ts:-1}) db.users.insert({a:1, b:1}) db.users.find({},{a:1, b:1}) db.users.find() db.users.find({age:33}) db.users.find({age:33},{a:1, b:1}) db.users.find({'age':{$lt:33}}) 创建索引 创建索引 插入记录 查询表 查询表 条件查询 条件查询 条件查询 条件查询 条件查询 Create INDEX users(name) idxname Create INDEX idxname users(name,ts DESC) Insert into users values(1, 1) Select a, b from users Select * from users Select * from users where age=33 Select a, b from users where age=33 select * from users where age<33 select * from users where age>33 db.users.find({'age':{$gt:33,$lte:40and age<=40 }}) select * from users where a=1 and db.users.find({a:1,b:'q'}) b='q' select * from users where a=1 or b=2 db.users.find( { $or : [ { a : 1 } , 条件查询 { b : 2 } ] } ) select * from users limit 1 db.users.findOne() 条件查询 模糊查询 模糊查询 获取表记录数 {'$gt': 获取表记录数 去掉重复值 排序 排序 获取存储路径 更新记录 更新记录 删除记录 删除所有的记录 删除数据库 删除表/collection 添加用户 readOnly-->false 添加用户 readOnly-->true 更改密码 删除用户 select * from users where name like db.users.find({name:/Joe/}) \"%Joe%\" select * from users where name like db.users.find({name:/^Joe/}) \"Joe%\" select count(1) from users Db.users.count() select count(1) from users where db.users.find({age: age>30 30}}).count() select DISTINCT last_name from db.users.distinct('last_name') users select * from users ORDER BY db.users.find().sort({name:-1}) name select * from users ORDER BY db.users.find().sort({name:-1}) name DESC EXPLAIN select * from users where db.users.find({z:3}).explain() z=3 update users set a=1 where b='q' update users set a=a+2 where b='q' delete from users where z=\"abc\" drop database IF EXISTS test; drop table IF EXISTS test; db.users.update({b:'q'}, {$set:{a:1}}, false, true) db.users.update({b:'q'}, {$inc:{a:2}}, false, true) db.users.remove({z:'abc'}) db. users.remove() use test db.dropDatabase() db.mytable.drop() db.addUser(„test‟, ‟test‟) db.addUser(„test‟, ‟test‟, true) db.addUser(\"test\db.system.users.remove({user:\"test\或者db.removeUser('test') use admin db.auth(„test‟, „test‟) db.system.users.find() show users db.printCollectionStats() db.printReplicationInfo() show profile 超级用户 用户授权 查看用户列表 查看所有用户 查看各collection的状态 查看主从复制状态 查看profiling db.copyDatabase('mail_addr','mail_addr_tmp') db.users.dataSize() db. users.totalIndexSize() 拷贝数据库 查看collection数据的大小 查询索引的大小 mongodb语法

MongoDB的好处挺多的,比如多列索引,查询时可以用一些统计函数,支持多条件查询,但是目前多表查询是不支持的,可以想办法通过数据冗余来解决多表查询的问题。

MongoDB对数据的操作很丰富,下面做一些举例说明,内容大部分来自官方文档,另外有部分为自己理解。 查询colls所有数据

db.colls.find() //select * from colls 通过指定条件查询

db.colls.find({„last_name‟: „Smith‟});//select * from colls where last_name=‟Smith‟ 指定多条件查询

db.colls.find( { x : 3, y : “foo” } );//select * from colls where x=3 and y=‟foo‟ 指定条件范围查询

db.colls.find({j: {$ne: 3}, k: {$gt: 10} });//select * from colls where j!=3 and k>10 查询不包括某内容

db.colls.find({}, {a:0});//查询除a为0外的所有数据

支持<, <=, >, >=查询,需用符号替代分别为$lt,$lte,$gt,$gte db.colls.find({ “field” : { $gt: value } } ); db.colls.find({ “field” : { $lt: value } } ); db.colls.find({ “field” : { $gte: value } } ); db.colls.find({ “field” : { $lte: value } } ); 也可对某一字段做范围查询

db.colls.find({ “field” : { $gt: value1, $lt: value2 } } ); 不等于查询用字符$ne

db.colls.find( { x : { $ne : 3 } } ); in查询用字符$in

db.colls.find( { “field” : { $in : array } } ); db.colls.find({j:{$in: [2,4,6]}}); not in查询用字符$nin

db.colls.find({j:{$nin: [2,4,6]}}); 取模查询用字符$mod

db.colls.find( { a : { $mod : [ 10 , 1 ] } } )// where a % 10 == 1 $all查询

db.colls.find( { a: { $all: [ 2, 3 ] } } );//指定a满足数组中任意值时 $size查询

db.colls.find( { a : { $size: 1 } } );//对对象的数量查询,此查询查询a的子对象数目为1的记录 $exists查询

db.colls.find( { a : { $exists : true } } ); // 存在a对象的数据 db.colls.find( { a : { $exists : false } } ); // 不存在a对象的数据 $type查询$type值为bsonhttp://bsonspec.org/数 据的类型值

db.colls.find( { a : { $type : 2 } } ); // 匹配a为string类型数据 db.colls.find( { a : { $type : 16 } } ); // 匹配a为int类型数据 使用正则表达式匹配

db.colls.find( { name : /acme.*corp/i } );//类似于SQL中like 内嵌对象查询

db.colls.find( { “author.name” : “joe” } ); 1.3.3版本及更高版本包含$not查询

db.colls.find( { name : { $not : /acme.*corp/i } } ); db.colls.find( { a : { $not : { $mod : [ 10 , 1 ] } } } ); sort()排序

db.colls.find().sort( { ts : -1 } );//1为升序2为降序 limit()对查询数据返回个数 db.colls.find().limit(10) skip()跳过某些数据 db.colls.find().skip(10)

snapshot()快照保证没有重复数据返回或对象丢失 count()统计查询对象个数

db.students.find({„address.state‟ : „CA‟}).count();//效率较高

db.students.find({„address.state‟ : „CA‟}).toArray().length;//效率很低 group()对查询结果分组和SQL中group by函数类似 distinct()返回不重复值

-----------------------------------------------我不是分割线-------------------------------------------------- 教程摘自互联网和整合翻译!

mongodb教程 第二讲

Mongo的安装

下载

最新(推荐)的安装MongoDB的方式是使用预构建二进制文件。 32位二进制文件

下载 并解压32位.zip文件。推荐使用 \"Production\" 构建包。(我已经制作了绿色版在群共享)

解压

解压二进制包到任意位置。为了方便,你可以将 \"mongo-xxxxxxx\" 重命名为 \"mongo\" 。

创建数据目录

MongoDB默认将数据存储在 /data/db 目录下,但是它不会自动创建目录。创建目录: C:\\> mkdir \\data C:\\> mkdir \\data\\db

当然你也可以从Windows Explorer创建目录。

启动并连接服务器

首次运行时的重要文件为:

 mongod.exe- 数据库服务器  mongo.exe- 管理shell

在Explorer里点击 mongod.exe 来启动服务器。或者在CMD窗口里启动。 C:\\> cd \\my_mongo_dir\\bin

C:\\my_mongo_dir\\bin > mongod

注意:也可以将服务器作为一个 [Windows服务] 来启动。我们可以稍后再这样做。 现在,通过在Explorer里双击 mongo.exe 或从CMD启动管理shell。默认情况下mongo.exe会建立到运行在 localhost 的 mongod 服务器的连接,并使用名为 test 的数据库。运行 mongo --help 查看其他选项。 C:\\> cd \\my_mongo_dir\\bin C:\\my_mongo_dir\\bin> mongo

> // mongo shell是连接到数据库的javascript shell > 3+3 6 > db test

> // 第一次写操作会创建数据库: > db.foo.insert( { a : 1 } ) > db.foo.find() { _id : ..., a : 1 }

恭喜你,你已经使用MongoDB保存和查询了第一个文档!

连接数据库

现在我们通过数据库的 shell 来实际操作一下。(注意:任何编程语言都可以通过合适的 驱动 进行类似的操作,只不过shell的方式更方便交互操作和管理。) 运行MongoDB JavaScript shell:

# 'mongo' 是shell执行文件。解压目录可能因安装方法和平台而不同。 $ bin/mongo

默认情况下shell将连接本机(localhost)的“test”数据库。你将看到: MongoDB shell version: 1.6.5 connecting to: test >

“connecting to:” 表明shell连接的数据库名。执行以下命令切换数据库: > use mydb

switched to db mydb

输入 help 可以看到一个简单的命令列表。 给有其他数据库经验的开发者的提示 在下面的例子中你可能会注意到,我们没有创建数据库和聚集。MongoDB并不用那么做。一旦你插入数据,MongoDB会建立对应的聚集和数据库。要是查询了不存在的聚集,Mongo就将其视为空的聚集。

使用 use 命令来切换数据库不会立即创建数据库 - 数据库会在首次插入数据时延迟创建。这意味着如果首次 use 一个数据库,该数据库不会在 show dbs 命令的列表里显示出来,直到插入数据。

向聚集中插入数据

让我们创建一个测试聚集,然后插入一些数据。我们将会新建两个对象 j 和 t , 然后将其存放在 things 聚集中。

下面的例子中,'>' 表示在shell命令提示符输入的命令。 > j = { name : \"mongo\" }; { \"name\" : \"mongo\" } > t = { x : 3 }; { \"x\" : 3 }

> db.things.save(j); > db.things.save(t); > db.things.find();

{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" } { \"_id\" : ObjectId(\"4d0d9738e34d147e5f68c487\"), \"x\" : 3 } >

注意几点:

 我们并没有预先定义聚集。数据库会在第一次插入操作时自动创建集。

 我们存储的文档可以拥有任意不同的“结构”。事实上在本例中,文档之间根本没有共同的数据元素。在实际应用中文档通常都以相同的结构保存在聚集里面。这种灵活意味着迁移或者扩展都非常容易。几乎不需要写脚本来执行诸如“alter table”之类的操作。  一旦被插入数据库,对象就被分配一个 [object ID](要是还没有的话)存储在 _id 域中

 你运行上面的例子时,你的ObjectID的值会有所不同。 下面再往聚集里面添加一些记录:

> for (var i = 1; i <= 20; i++) db.things.save({x : 4, j : i}); > db.things.find();

{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" } { \"_id\" : ObjectId(\"4d0d9738e34d147e5f68c487\"), \"x\" : 3 }

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c488\"), \"x\" : 4, \"j\" : 1 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c4\"), \"x\" : 4, \"j\" : 2 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48a\"), \"x\" : 4, \"j\" : 3 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48b\"), \"x\" : 4, \"j\" : 4 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48c\"), \"x\" : 4, \"j\" : 5 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48d\"), \"x\" : 4, \"j\" : 6 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48e\"), \"x\" : 4, \"j\" : 7 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48f\"), \"x\" : 4, \"j\" : 8 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c490\"), \"x\" : 4, \"j\" : 9 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c491\"), \"x\" : 4, \"j\" : 10 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c492\"), \"x\" : 4, \"j\" : 11 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c493\"), \"x\" : 4, \"j\" : 12 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c494\"), \"x\" : 4, \"j\" : 13 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c495\"), \"x\" : 4, \"j\" : 14 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c496\"), \"x\" : 4, \"j\" : 15 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c497\"), \"x\" : 4, \"j\" : 16 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c498\"), \"x\" : 4, \"j\" : 17 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c499\"), \"x\" : 4, \"j\" : 18 } has more

注意这里并没有列出所有的文档 - shell 会默认显示20个。先前已经有两个文档在聚集里面了,所以这里只能看见新插入的前18个文档。

要是想接着看结果,可以用 it 命令。接着上面的例子往下: { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c498\"), \"x\" : 4, \"j\" : 17 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c499\"), \"x\" : 4, \"j\" : 18 } has more > it

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49a\"), \"x\" : 4, \"j\" : 19 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49b\"), \"x\" : 4, \"j\" : 20 }

通常,find()会返回一个游标对象,但是在上面那个例子中,我们并没有将游标赋值给一个变量。所以shell自动的移动游标,并且把初始化后的结果返回给我们,同时允许我们通过 it

命令继续移动游标。

但是我们仍然可以直接使用游标,在下一部分中将讨论如何这样做。

使用查询访问数据

在我们对查询进行深入讨论之前,我们先来看看如何通过一个游标对象操作查询结果。我们将使用简单的find()查询函数,它会返回一个聚集中的所有数据。随后我们看看如何创建一些特定的查询。

在使用 mongo shell 的时候,为了查看所有聚集中的数据元素,我们需要显式的使用从find()操作返回的游标。

让我们使用相同的查询,但是这次我们使用find()返回的游标,并且在while循环中移动游标:

> var cursor = db.things.find();

> while (cursor.hasNext()) printjson(cursor.next());

{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" } { \"_id\" : ObjectId(\"4d0d9738e34d147e5f68c487\"), \"x\" : 3 }

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c488\"), \"x\" : 4, \"j\" : 1 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c4\"), \"x\" : 4, \"j\" : 2 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48a\"), \"x\" : 4, \"j\" : 3 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48b\"), \"x\" : 4, \"j\" : 4 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48c\"), \"x\" : 4, \"j\" : 5 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48d\"), \"x\" : 4, \"j\" : 6 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48e\"), \"x\" : 4, \"j\" : 7 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48f\"), \"x\" : 4, \"j\" : 8 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c490\"), \"x\" : 4, \"j\" : 9 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c491\"), \"x\" : 4, \"j\" : 10 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c492\"), \"x\" : 4, \"j\" : 11 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c493\"), \"x\" : 4, \"j\" : 12 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c494\"), \"x\" : 4, \"j\" : 13 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c495\"), \"x\" : 4, \"j\" : 14 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c496\"), \"x\" : 4, \"j\" : 15 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c497\"), \"x\" : 4, \"j\" : 16 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c498\"), \"x\" : 4, \"j\" : 17 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c499\"), \"x\" : 4, \"j\" : 18 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49a\"), \"x\" : 4, \"j\" : 19 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49b\"), \"x\" : 4, \"j\" : 20 }

上述例子展示了游标的循环方式,hasNext()函数告知是否还有文档返回,而next()函数则返回下一个文档对象。同时我们还使用了内嵌的tojson()函数来把document的对象显示成JSON数据格式。

当使用JavaScript shell 时,我们还可以享用其语言本身的函数式特性:可以对游标调用 forEach 。还拿上面的例子来说,直接在游标处将使用 forEach() 来代替while循环: > db.things.find().forEach(printjson);

{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" } { \"_id\" : ObjectId(\"4d0d9738e34d147e5f68c487\"), \"x\" : 3 }

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c488\"), \"x\" : 4, \"j\" : 1 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c4\"), \"x\" : 4, \"j\" : 2 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48a\"), \"x\" : 4, \"j\" : 3 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48b\"), \"x\" : 4, \"j\" : 4 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48c\"), \"x\" : 4, \"j\" : 5 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48d\"), \"x\" : 4, \"j\" : 6 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48e\"), \"x\" : 4, \"j\" : 7 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48f\"), \"x\" : 4, \"j\" : 8 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c490\"), \"x\" : 4, \"j\" : 9 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c491\"), \"x\" : 4, \"j\" : 10 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c492\"), \"x\" : 4, \"j\" : 11 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c493\"), \"x\" : 4, \"j\" : 12 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c494\"), \"x\" : 4, \"j\" : 13 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c495\"), \"x\" : 4, \"j\" : 14 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c496\"), \"x\" : 4, \"j\" : 15 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c497\"), \"x\" : 4, \"j\" : 16 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c498\"), \"x\" : 4, \"j\" : 17 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c499\"), \"x\" : 4, \"j\" : 18 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49a\"), \"x\" : 4, \"j\" : 19 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49b\"), \"x\" : 4, \"j\" : 20 }

在{{forEach()}}里必须定义一个函数来对游标中的每个文档进行操作。 在 mongo shell 中,也可以把游标当作数组处理: > var cursor = db.things.find(); > printjson(cursor[4]);

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48a\"), \"x\" : 4, \"j\" : 3 }

当这样使用游标时,注意这会将最大访问数据(上面的例子中的cursor[4])以下的所有数据都同时加载到内存中。这对大结果集非常不合适,会导致内存不够用的。当返回结果数量很大时,游标应该作为迭代器使用。

除了用数组的风格来操作游标,也可以干脆将游标转换正的数组: > var arr = db.things.find().toArray(); > arr[5];

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48b\"), \"x\" : 4, \"j\" : 4 }

请注意这种数组特性是[Mongo交互Shell]特有的,但并不是所有的驱动都支持。

MongoDB游标并不做快照。如果在第一次到最后一次调用 next 之间,你或别人对数据进行了修改,那么修改可能被返回,也可能不返回。要是想做快照查询的话得使用显式锁。

定制查询结果

现在我们知道了如何使用查询返回的游标对象,下面看看如何通过修改查询来定制结果。 通常,可以通过创建一种键值相匹配的“查询文档”来实现定制查询。

这些用实例更能说明问题。在下面的例子里,我们将给出SQL查询示例,并在MongDB的 mongo shell 中展示相同的查询。这种指定的查询对于MongoDB来说是基本方式,而且你

也会在任何驱动和语言环境中找到类似的通用功能。 SELECT * FROM things WHERE name=\"mongo\"

> db.things.find({name:\"mongo\{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" }

SELECT * FROM things WHERE x=4

> db.things.find({x:4}).forEach(function(x) {print(tojson(x));}); { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c488\"), \"x\" : 4, \"j\" : 1 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c4\"), \"x\" : 4, \"j\" : 2 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48a\"), \"x\" : 4, \"j\" : 3 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48b\"), \"x\" : 4, \"j\" : 4 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48c\"), \"x\" : 4, \"j\" : 5 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48d\"), \"x\" : 4, \"j\" : 6 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48e\"), \"x\" : 4, \"j\" : 7 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48f\"), \"x\" : 4, \"j\" : 8 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c490\"), \"x\" : 4, \"j\" : 9 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c491\"), \"x\" : 4, \"j\" : 10 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c492\"), \"x\" : 4, \"j\" : 11 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c493\"), \"x\" : 4, \"j\" : 12 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c494\"), \"x\" : 4, \"j\" : 13 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c495\"), \"x\" : 4, \"j\" : 14 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c496\"), \"x\" : 4, \"j\" : 15 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c497\"), \"x\" : 4, \"j\" : 16 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c498\"), \"x\" : 4, \"j\" : 17 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c499\"), \"x\" : 4, \"j\" : 18 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49a\"), \"x\" : 4, \"j\" : 19 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49b\"), \"x\" : 4, \"j\" : 20 }

查询表达式本身就是一个文档对象,如果是一个类似于{a:A, b:B, ...}的文档查询对象,则表示”where a==A and b==B and ...”。

MongoDB也允许返回”部分文档”,也就是返回一个数据库文档的元素子集。您只要通过使用find()函数的第二个参数就可以做到这一点。

例如,我们在上面 find({x:4}) 的例子中,加一个参数来只返回j域的数据: SELECT j FROM things WHERE x=4

> db.things.find({x:4}, {j:true}).forEach(printjson);

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c488\"), \"j\" : 1 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c4\"), \"j\" : 2 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48a\"), \"j\" : 3 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48b\"), \"j\" : 4 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48c\"), \"j\" : 5 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48d\"), \"j\" : 6 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48e\"), \"j\" : 7 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c48f\"), \"j\" : 8 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c490\"), \"j\" : 9 }

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c491\"), \"j\" : 10 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c492\"), \"j\" : 11 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c493\"), \"j\" : 12 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c494\"), \"j\" : 13 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c495\"), \"j\" : 14 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c496\"), \"j\" : 15 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c497\"), \"j\" : 16 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c498\"), \"j\" : 17 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c499\"), \"j\" : 18 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49a\"), \"j\" : 19 } { \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c49b\"), \"j\" : 20 }

需要注意的是\"_id\"域是每次都要被返回的。

findOne() - 语法

为了方便起见,mongo shell(和其他驱动)能避免让你用编程来处理游标,你只需要通过findOne()函数就能获得一个文档。findOne()和find()使用相同的参数,但是它不返回游标,而是从数据库中返回第一个文档,或者没有匹配条目时返回 null。 例如,我们可以通过很多种方式检索一个 name=='mongo' 的文档,包括在游标中调用next()函数(当然,要验证完是否为 null 之后),或者把游标看做一个数组然后访问数组下标为0的元素。

但是,findOne()函数是既方便又高效的:

> printjson(db.things.findOne({name:\"mongo\

{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" }

由于只从数据库返回一个对象,这种方式更加高效,而且在数据库和网络传输上做的工作更少。这种方式等价于find({name:\"mongo\。

使用 limit() 结果集

通过 limit() 方法可以指定返回结果的最大数量,这样就能控制查询结果的大小了。

强力推荐这种使用方式,它可以大大提高性能,因为这样减少了数据库的工作量,也减少了网络中的数据流量。举个例子: > db.things.find().limit(3);

{ \"_id\" : ObjectId(\"4d0d9727e34d147e5f68c486\"), \"name\" : \"mongo\" } { \"_id\" : ObjectId(\"4d0d9738e34d147e5f68c487\"), \"x\" : 3 }

{ \"_id\" : ObjectId(\"4d0d99ace34d147e5f68c488\"), \"x\" : 4, \"j\" : 1 }

如果你对某个方法做的事情好奇,你可以在输入时不带 (),然后shell会打印出该方法的源代码,例如: > printjson function (x) {

print(tojson(x)); }

mongo是一个完备的JavaScript shell,所以任何JavaScript方法,语法或类都可以在shell中使用。除此以外,MongoDB还定义一些自己的类和全局变量(如 db)。

UNIX/LINUX连接

MongoDB是一个数据库服务器,在等待客户端连接的时候,可以以前台或后台方式运行。当你启动MongoDB后,可以看到如下输出: ~/$ ./mongod #

# some logging output #

Tue Mar 9 11:15:43 waiting for connections on port 27017

Tue Mar 9 11:15:43 web admin interface listening on port 28017

输出将停在这里,并等待客户端连接到27017端口。一旦你连接到数据库并开始发送命令,它将继续输出正执行的操作。你可以使用任何一种MongoDB的 驱动 或是 Mongo shell 来连接到数据库。

但你_不能_通过浏览器访问27017端口 http://localhost:27017。数据库不接受HTTP方式访问该端口。

标准连接字符串格式

以下列出的uri样式并非被所有的数据库驱动所支持,请参考各驱动自己的文档,查看各驱动支持的连接字符串uri形式。如果下面的样式不支持,那么驱动会有自己的指定连接的替代方式。

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

 mongodb://是一个必填的前缀,它标识当前字符串是标准连接格式。

 {{username:password@}}可选。给出用户名和密码后,驱动将在连接到数据库后尝试登录。

 host1uri里唯一的必填项,数据库的连接地址。  :portX可选。默认连接到27017端口。

 /database是希望连接到的数据库名,只有在提供 username:password@ 后该值才有效。如果不指定,默认将连接\"admin\"数据库。

可以任意指定多个数据库和端口,这用于实现连接到replica pairs/sets。 可选项有:

connect=direct|replicaset

o direct: 直接建立一个到服务器的连接。如果指定了多个host,将按先后顺序挨个尝试建立连接,直到连接建立成功为止。如果只指定了一个host,则 direct 为默认值。

o replicaset: 使用creplica set semantics建立连接(即使只提供了一个host)。指定的host作为种子列表来查找完整的replica set。当指定多个host时 replicaset 为默认值。

replicaset=name

o 驱动验证建立连接的replica set的名字。隐含 connect=replicaset。

slaveok=true|false

o true: 对于 connect=direct 模式,驱动对列表中的第一个服务器建立连接,即使它不是主服务器。对 connect=replicaset 模式,驱动将所有写操作发送到主节点,将所有读操作按round robin顺序分发到从节点。

o false: 对 connect=direct 模式,驱动按顺序尝试所有host直到找到主节点。对 connect=replicaset 模式,驱动将只连接到主节点,并将所有读操作和写操作都发送到主节点。

safe=true|false

o true: 驱动在每次更新操作后都发送 getlasterror 命令以确保更新成功(参考 w 和 wtimeout)。

o false: 驱动每次更新操作后不发送 getlasterror 命令。

w=n

o 驱动给 getlasterror 发送 { w : n } 命令。隐含 safe=true。

wtimeout=ms

o 驱动给 getlasterror 添加 { wtimeout : ms } 参数。隐含 safe=true。

fsync=true|false

o true: 驱动给 getlasterror 添加 { fsync : true } 参数。隐含 safe=true。 o false: 驱动不添加 fsync 参数。

示例

连接到一个运行在本机默认端口(27017)的MongoDB mongodb://localhost

连接到一个运行在本机默认端口(27017)的MongoDB,并以用户名\"fred\"和密码\"foobar\"登录,登录后将默认使用admin数据库 mongodb://fred:foobar@localhost

连接到一个运行在本机默认端口(27017)的MongoDB,并以用户名\"fred\"和密码\"foobar\"登录,登录后将使用baz数据库

mongodb://fred:foobar@localhost/baz

连接到一个replica pair,一台服务器在example1.com,另一台在example2.com mongodb://example1.com:27017,example2.com:27017

连接到本机的一个replica set(端口分别为27017,27018,27019) mongodb://localhost,localhost:27018,localhost:27019

连接到三台服务器的replica set,将所有写操作发送到主节点,所有读操作分发到从节点

mongodb://host1,host2,host3/?slaveok=true

连接到第一台服务器并响应,无论它是replica set的一台,也无论它是主节点还是从节点

mongodb://host1,host2,host3/?connect=direct;slaveok=true

注:这种类型的连接字符串可用于在你偏好使用某台服务器但有可供替换的服务器的时候。 使用safe模式连接到本机

mongodb://localhost/?safe=true

使用safe模式连接到replica set,等待备份在至少两台机器上完成,timeout时间为2秒

mongodb://host1,host2,host3/?safe=true;w=2;wtimeout=2000

连接池

每个TCP连接将对应一个数据库线程。因此强烈建议你使用某种形式的连接池技术。幸运的是,大部分官方数据库驱动已经内置实现了这个功能。但如果你使用CGI或是PHP,对应每个新的请求可能启动一个新的应用进程,这种情况下需要特别注意连接的处理。

交互shell

简介

MongoDB 发布包 包含了 bin/mongo,它是MongoDB交互shell环境。 该工具是一个JavaScript shell,它允许你从命令行向MongoDB发起命令。 该shell用于:

 查看数据库的内容  测试查询  创建索引  其他管理功能

Shell数据类型

数字

默认情况下shell认为数字均为浮点数。你可以使用一个shell内嵌的LongNumber()类来使用位整数。如果你想要整型或长整型的 [BSON] 数据,你可能会看到以下内容:

\"bytes\" : {

\"floatApprox\" : 575175

}

或者在1.6+的版本中对更大的数字这样显示:

{..., \"bytes\" : NumberLong(5284376243087482000) ,...}

注意在1.6之前的版本中长数字会这样显示:

\"bytes\" : {

\"floatApprox\" : 5284376243087482000, \"top\" : 12303721, \"bottom\" : 4240317554 }

而且,用javascript设置或增长任何数字会把数据类型改成浮点数。 时间

Date() 方法返回一个字符串,而“new Date()”则会返回一个对象(你用它来存储数据)。

> Date()

Sun May 02 2010 19:07:40 GMT-0700 (Pacific Daylight Time) > new Date()

\"Sun May 02 2010 19:07:43 GMT-0700 (Pacific Daylight Time)\" > typeof(new Date()) object

> typeof(Date()) string

//1.7+的版本会打印如下内容 > new Date()

ISODate(\"2010-11-29T19:41:46.730Z\")

启动 Shell

交互shell包含在MongoDB标准发布包里。在发布包的根目录运行以下命令启动shell: ./bin/mongo

将 mongo_distribution_root/bin 加到 PATH 环境变量中,这样就可以在任何地方输入 mongo 命令来启动了。

如果启动时不加参数,它将默认连接本机 27017 端口的 “test” 数据库。可以使用输入 db 来查看当前连接的数据库: ./mongo

connecting to: test > db

test

可以给 mongo 命令传递可选参数来指定数据库地址,端口甚至初始连接的数据库: ./mongo foo 连接本机的 foo 数据库 ./mongo 192.168.13.7/foo 连接192.168.13.7的 foo 数据库

./mongo dbserver.mydomain.com/foo 连接dbserver.mydomain.com的 foo 数据库 ./mongo 192.168.13.7:9999/foo 连接192.168.13.7且端口为9999的 foo 数据库

连接

如果你没有通过命令行建立连接,可以用使用以下命令: conn = new Mongo(host); db = conn.getDB(dbname); db.auth(username,password);

这里的 host 是一个字符串,它是你要连接的机器的名字或地址及端口(例如 \"192.168.13.7\" 或 \"192.168.13.7:9999\")。注意,host是一个可选参数,如果你想连接本机,则可以省略该参数(例如 conn = new Mongo() )。 另外你可以使用 connect 辅助方法:

> db = connect(\"localhost:27020/mytestdb\"); // 使用非标准端口的例子

基本命令

下面是提供可用数据库,聚集信息的三个基本命令。 show dbs 显示当前连接服务器的所有数据库 use db_name 切换到同一服务器的 db_name 数据库 show collections 显示当前数据库的所有聚集的列表

查询

mongo 使用 JavaScript API 来和数据库交互。由于 mongo 是一个完整的 JavaScript shell,db 变量表示当前数据库连接。

可以通过指定聚集名作为 db 对象的属性然后调用 find() 方法来查询聚集。例如: db.foo.find();

这将显示 foo 聚集里的前20个对象。调用find()方法之后输入 it 命令将会显示紧接着的20个对象。

可以通过设置 shellBatchSize 来改变默认返回对象数量: DBQuery.shellBatchSize = #

如果shell不接受该聚集名(例如聚集名以数字开头或包含空格等),则可以使用 db['foo'].find() 来代替

插入数据

可以简单的创建JavaScript对象并调用 save() 方法来插入数据。例如在聚集 foo 中保存 {name: \"sara\对象in a collection called foo: db.foo.save({ name : \"sara\

注意MongoDB会隐式的创建不存在的聚集。

修改数据

例如你想修改某人的地址,你可以使用如下 mongo 命令: person = db.people.findOne( { name : \"sara\" } ); person.city = \"New York\"; db.people.save( person );

删除数据

db.foo.drop() db.foo.remove()

删除整个 foo 聚集 删除聚集里的所有对象

删除聚集里 name 为 sara 的对

db.foo.remove( { name : \"sara\" } )

索引

db.foo.getIndexKeys() 返回所有有索引的域 db.foo.ensureIndex({ _field_ : 1 }) 对 field 域创建索引

行连续

如果一行包含 '(' 或者 '{' 字符,则shell会在解释之前请求更多输入: > function f() { ... x = 1; ... } >

你可以输入 Ctrl-C 退出 “...” 模式并结束一行输入。

Shell 参考

命令行

--help --nodb --shell

显示命令行参数

不连接数据库方式启动,稍后可以使用 new Mongo() 或 connect() 来建立连接

从命令行运行完一个 .js 文件后,停留在shell中,而不是结束

特殊命令

非JavaScript的辅助指令: help db.help()

db.myColl.help() show dbs use dbname show collections show users show profile

显示帮助

显示 db 方法帮助 显示聚集的方法帮助

打印服务器上所有数据库的列表

设置db变量来指明使用服务器上的 dbname 数据库

打印当前数据库的所有聚集 打印当前数据库的用户

打印最近耗时大于1ms的profiling操作

基本的Shell Javascript操作

db

db.auth(user,pass) coll = db.collection cursor = coll.find() coll.remove(objpattern)

指向当前数据库对象和连接的变量,已经在你的实例里定义好。 数据库认证(如果运行安全模式的话) 访问数据库里特定的 collection

查找聚集里所有的对象。参考 [查询]。 从聚集里删除匹配的对象。

objpattern是一个指定匹配的域的对象,例如:coll.remove( { name: \"Joe\" } );

在聚集中保存对象,如果已经存在的话则更新它。

如果对象有 presave 方法,则会在保存到数据库之前(插入和更新之前)调用该方法。

向聚集中插入对象。不会检查该对象是否已经存在聚集中(即,不是 upsert)

在聚集中更新对象。

对 name 建索引。如果索引存在则不做任何事。

删除 coll 聚集

返回当前连接的另一个数据库。它允许跨数据库查询,例如:db.getSisterDB('production').getCollectionNames()

coll.save(object)

coll.insert(object) coll.update(...)

coll.ensureIndex( { name : 1 } ) coll.drop()

db.getSisterDB(name)

查询

coll.find() it

查询所有文档

循环上次 find() 调用返回的游标

coll.find( criteria );

coll.findOne( criteria );

coll.find( criteria, fields );

coll.find().sort( {field:1[, field:1] }); coll.find( criteria ).sort( { field : 1 } ) coll.find( ... ).limit(n) coll.find( ... ).skip(n ) coll.count()

coll.find( ... ).count()

查询聚集中匹配 criteria 的对象。例如:coll.find( { name: \"Joe\" } );

查询并返回一个对象。如果没有找到则返回 null。如果你只需要返回一个对象,这个方法比 find() as limit(1) 效率更高。如果元素类型是字符串,数字或时间,你还可以使用正则表达式:coll.find( { name: /joe/i } );

查询对象里特定的域。例如:coll.find( {}, {name:true} ); 对返回结果进行排序(field ASC)。使用 -1 表示 DESC。

查找匹配 criteria 的对象,并对 field 进行排序。 结果返回 n 行。如果你只需要某几行数据,推荐这样做来获得最优性能。 跳过 n 行结果。

返回聚集里对象的总数。

返回匹配该查询的对象总数。注意,该返回会忽略 limit 和 skip。比如有100行记录匹配该查询,但是limit为10,count() 仍会返回100。这比你自己循环更快,但仍然需要消耗些时间。

更多信息请参考 [查询]。

错误检查

[{{db.getLastError()}}] db.getPrevError() db.resetError()

返回上次操作的错误 返回之前操作的错误 清除错误记录

管理命令

db.cloneDatabase(fromhost) db.copyDatabase(fromdb, todb, fromhost) db.repairDatabase() db.addUser(user,pwd) db.getCollectionNames() db.dropDatabase()

从另外指定的主机拷贝当前数据数据库。fromhost必须为noauth模式。

拷贝fromhost的fromdb数据库到当前服务器的todb数据库。fromhost必须为noauth模式。

修复当前数据库。如果数据库很大则该操作会非常慢。 给当前数据库添加用户。 获得所有聚集的列表。 删除当前数据库。

打开额外连接

db = connect(\":/\") conn = new Mongo(\"hostname\") db =

打开一个新的数据库连接。一个shell可能有多个连接,但是shell

自动的getLastError只用于 'db' 变量。

打开一个新的服务器连接。然后可以使用 getDB() 来选择一个数据库。

对一个连接选择一个特定的数据库。

conn.getDB(\"dbname\")

其他

Object.bsonsize(db.foo.find

打印一个数据库对象的bson大小(mongo 版本1.3及以上)

One())

db.foo.findOne().bsonsize() 打印一个数据库对象的bson大小 (mongo 版本1.3之前)

数据库指令

介绍

Mongo数据库有数据库指令(database command)概念。使用这些命令可以让数据库执行某中操作或是返回有关数据库当前状态的某些信息。

一条指令将被作为针对 $cmd 集合的一种特殊的查询语句发送到数据库。数据库执行后,将返回一个单文档对象作为命令的返回结果,可以用 findOne() 获得。 基本的命令格式为:

db.$cmd.findOne( { : [, options] } );

在命令行环境下,可以执行:

db.runCommand( { : [, options] } );

例如,检查当前数据库profile level的设置,可以执行: > db.runCommand({profile:-1}); {

\"was\" : 0.0 , \"ok\" : 1.0 }

多数数据库驱动提供了对数据库指令的封装方法,以方便使用。例如mongo shell提供 > db.getProfilingLevel() 0.0

该方法的实现如下:

> print( db.getProfilingLevel ) function () {

var res = this._dbCommand({profile:-1}); return res ? res.was : null; }

> print( db._dbCommand ) function (cmdObj) {

return this.$cmd.findOne(cmdObj); }

多数指令都有类似的简便用法 - 参见各数据库驱动的相关文档。

指令

某些特殊的操作只有管理员才能执行。这些特殊的操作将在{{admin}}数据库中执行。 > use admin;

> db.runCommand(\"shutdown\"); // shut down the database

如果当前数据库不是'admin', 你可以直接使用_adminCommand方法去操作: > db._adminCommand(\"shutdown\");

(对于这个操作,还有简便用法db.shutdownServer。)

获得指令帮助信息

使用commandHelp命令去获得某个指令的相关信息: > db.commandHelp(\"datasize\")

help for: datasize example: { datasize:\"blog.posts\ NOTE: This command may take awhile to run

克隆数据库

Mongo数据库包含服务器至服务器之间的克隆指令。

// copy an entire database from one name on one server to another // name on another server. omit to copy from one // name to another on the same server.

db.copyDatabase(, , ); // if you must authenticate with the source database

db.copyDatabase(, , , , ); // in \"command\" syntax (runnable from any driver):

db.runCommand( { copydb : 1, fromdb : ..., todb : ..., fromhost : ... } ); // command syntax for authenticating with the source:

n = db.runCommand( { copydbgetnonce : 1, fromhost: ... } );

db.runCommand( { copydb : 1, fromhost: ..., fromdb: ..., todb: ..., username: ..., nonce: n.nonce, key: } );

// clone the current database (implied by 'db') from another host var fromhost = ...;

print(\"about to get a copy of database \" + db + \" from \" + fromhost); db.cloneDatabase(fromhost);

// in \"command\" syntax (runnable from any driver): db.runCommand( { clone : fromhost } );

后面几章讲详细介绍索引,插入,查询,更新,删除等具体实例

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务