Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25152
  • 博文数量: 13
  • 博客积分: 464
  • 博客等级: 下士
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-19 21:58
文章分类

全部博文(13)

分类: NOSQL

2017-04-06 09:15:25

【介绍】

mongo shell是一个与MongoDB的JavaScript交互接口,可执行查询、更新和管理操作,是MongoDB部署包中的组件之一,一旦安装并启动MongoDB,即可通过mongo shell连接运行中的MongoDB实例

【打开mongo shell】

使用mongo shell通过默认的端口连接本机上运行的MongoDB实例:

1. 进入MongoDB安装目录

   $ cd

2. 启动mongo shell

   $ ./bin/mongo

   如果已将/bin路径添加到环境变量PATH里,只需键入mongo即可

当无参数运行mongo时,mongo shell会尝试连接运行在localhost:27017网络接口上的MongoDB

【.mongorc.js文件】

当被启动时,mongo会检查当前系统用户HOME目录下名为.mongorc.js的JavaScript文件,如果存在,mongo会是启动时解读该文件里的内容

如果使用shell去执行一个JavaScript文件或表达式,即使用--eval选项或指定一个.js文件,mongo将在执行完JavaScript后读取.mongorc.js文件

可以使用--norc选项以禁止读取该文件

【使用mongo shell】

显示当前使用的数据库,键入db:

> db

该操作会返回test,这是默认连接的数据库,要切换数据库,执行use命令:

> use

列出可用的数据库,执行show命令:

> show dbs

也可使用db.getSiblingDB()方法去访问另一个数据库,而不需要切换当前数据库上下文

能够切换到不存在的数据库,当第一次在该库里存储数据时,例如创建一个集合,MongoDB将创建该库,如下,在执行insertOne()操作后,即会创建数据库myNewDatabase,也会创建集合myCollection:

> use myNewDatabase
> db.myCollection.insertOne( { x: 1 } );

db.myCollection.insertOne()是mongo shell中可用方法之一

- db引用当前数据库
- myCollection是集合名

如果使用mongo shell不支持的集合名,例如名字中包含空格、横杠,或以数字开头,则可使用以下两种方式引用集合:

- db["3test"].find()
- db.getCollection("3test").find()

【格式化输出结果】

db.collection.find()方法返回一个结果集游标,在mongo shell里,如果返回的游标未用var关键字分配给一个变量,则游标自动迭代20次每次返回1个文档,即返回匹配查询最先20个文档,然后给出 Type it 提示符,键入it回车后再迭代20次

要格式化输出的结果集,加上.pretty(),如下:

> db.myCollection.find().pretty()

另外,可以在mongo shell里使用以下print方法:

- print() 无格式打印
- print(tojson()) 以JSON格式打印,等同于printjson()
- printjson() 以JSON格式打印,等同于print(tojson())

【mongo shell里的多行操作】

如果结束一行时只有左括号(如(、{或[),则以下的行都会以省略号开头(...),直到输入右括号(如)、}或]),因为在执行代码前,mongo shell会等待所有的括号成对出现,例如:

> if ( x > 0 ) {
... count++;
... print (x);
... }
>

如果连续回车输入两空行,可以退出续行模式,如下例;

> if (x > 0
...
...
>

【Tab补全和其他快捷键】

mongo shell支持多项快捷键,例如:

- 使用上下箭头键翻滚命令历史
- 使用键自动补全方法名或集合名,如有多个可用的方法或集合则会列出

【退出mongo shell】

键入quit()回车,或使用


== 配置mongo shell ==

【自定义提示符】

在mongo shell里通过设置prompt变量可以修改提示符内容,prompt变量可以使用JavaScript代码,也可以是JavaScript函数以显示动态的提示符信息

将提示符代码写入.mongorc.js文件中,则每次进行mongo shell时都会起效

> 自定义提示符以显示操作数
  执行以下代码,创建mongo shell提示符以显示当前会话执行的操作次数

cmdCount = 1;
prompt = function() {
             return (cmdCount++) + "> ";
         }

> 自定义提示符以显示数据库和主机名
  执行以下代码,创建mongo shell提示符为"@$"格式

host = db.serverStatus().host;
prompt = function() {
             return db+"@"+host+"$ ";
         }

> 自定义提示符以显示运行时长和对象个数
  执行以下代码,创建mongo shell提示符包含mongod运行时间和当前数据库下的集合数

prompt = function() {
           return "Uptime:"+db.serverStatus().uptime+" Documents:"+db.stats().objects+" > ";
         }

【在mongo shell里使用外部编辑器】

在启动mongo shell前,通过设置环境变量EDITOR可在mongo shell里使用喜爱的编辑器

$ export EDITOR=vim
$ mongo

进入mongo shell后,使用edit命令可编辑变量或函数,如下:

1. 定义一个myFunction函数:

> function myFunction () { }

2. 编辑该函数:

> edit myFunction

该命令会打开vim编辑会话,当完成编辑时,保存退出vim

3. 在mongo shell里,键入myFunction可以查询函数定义,显示编辑保存后的结果

> myFunction

mongo shell解读外部编辑器编写的代码时,可能会根据JavaScript编译器需要调整代码,例如将1+1转换成2或移除注释,这种改变只会使代码在不同的JavaScript版本下有不同的外观,但不会影响到代码的语义

【调整mongo shell批处理大小】

JavaScript方法 db.collection.find() 用于从集合里检索文档,该方法返回一个结果集游标

如前文所述,在mongo shell里,如果返回的游标未用var关键字分配给一个变量,则游标自动迭代20次每次返回1个文档,即返回匹配查询最先20个文档,然后给出 Type it 提示符,键入it回车后再迭代20次

可以设置 DBQuery.shellBatchSize 属性以调整这默认为20的文档返回数,下例将其设置为10:

> DBQuery.shellBatchSize = 10;


== 获得mongo shell帮助 ==

【命令行帮助】

要查看可用于启动mongo shell的选项列表,在命令行使用--help选项即可

$ mongo --help

【mongo shell帮助】

要查看帮助项列表,在mongo shell里键入help即可

> help

【数据库帮助】

在mongo shell里:

- 查看该MongoDB实例里的数据库列表,使用 show dbs 命令
- 查看当前数据库上可用方法列表,执行 db.help() 方法
- 在mongo shell里查看一个方法的实现,键入不带括号的 db. 即可

【集合帮助】

在mongo shell里:

- 查看当前数据库的集合列表,使用 show collections 命令
- 查看集合对象上可用的方法列表,使用 db..help() 方法
- 查看集合方法的实现,键入不带括号的 db.. 即可

【游标帮助】

当在mongo shell里执行find()方法读取数据时,可以使用多种游标方法来调整find()行为,以及多种JavaScript方法来处理find()方法返回的游标

- 列出可用的修饰符和游标处理方法,使用 db.collection.find().help() 命令
- 查看游标方法的实现,键入不带括号的 db..find(). 即可

列举些有用的游标处理方法:

- hasNext() 检查游标是否仍有方法可以返回
- next() 返回文档,并且游标位置前进一位
- forEach() 迭代整个游标,并用处理每个由游标返回的文档,使用一个参数对应每次迭代返回的文档

【包装对象帮助】

在mongo shell里查看包装对象的可用方法,例如BinData(),在mongo shell里键入 help misc 即可


== 编写mongo shell脚本 ==

可在mongo shell里编写JavaScript脚本,去操作MongoDB里的数据和执行管理操作

【打开新连接】

在mongo shell的JavaScript脚本中,可使用Mongo()构造函数实例化一个数据连接:

- new Mongo()
- new Mongo()
- new Mongo()

下例,实例化一个新连接,该MongoDB实例运行在localhost和默认端口上,并使用getDB()方法设置全局变量db为myDatabase:

> conn = new Mongo();
> db = conn.getDB("myDatabase");

如果连接的MongoDB实例启用了访问控制,可使用db.auth()方法认证

此外,也可使用connect()方法去连接MongoDB实例,下例,连接到一个运行在localhost上端口为27020的MongoDB实例,并设置全局变量db为myDatabase:

> db = connect("localhost:27020/myDatabase");

【mongo shell交互和脚本的不同】

当写mongo shell脚本时,要注意以下几点:

- 设置db变量,使用getDB()方法或connect()方法,可以分配数据库引用给任何变量

- 写操作默认使用 { w: 1 } 作为写确认,如果执行批量操作,使用Bulk()方法

  在MongoDB 2.6之前,要显式调用 db.getLastError() 方法等待写操作确认

- 不能使用任何mongo shell帮助,如use 、show dbs等,要使用对应的JavaScript语句

  No    Shell Helpers            JavaScript Equivalents
  --    ------------------------    -------------------------------------------
  1.    show dbs, show databases    db.adminCommand('listDatabases')
  2.    use             db = db.getSiblingDB('')
  3.    show collections        db.getCollectionNames()
  4.    show users            db.getUsers()
  5.    show roles            db.getRoles({showBuiltinRoles: true})
  6.    show log         db.adminCommand({ 'getLog' : '' })
  7.    show logs            db.adminCommand({ 'getLog' : '*' })
  8.    it                cursor = db.collection.find()
                      if ( cursor.hasNext() ){
                        cursor.next();
                      }

- 在交互模式下,mongo直接输出操作结果,包含游标返回的数据,在脚本模式下,要使用print()函数,或用printjson()返回JSON格式,例如,输出所有游标返回的项目,使用以下JavaScript代码:

  > cursor = db.collection.find();
  > while ( cursor.hasNext() ) {
  >   printjson( cursor.next() );
  > }

【脚本】

- eval选项
  使用--eval选项向mongo传递JavaScript语句,如下:

  $ mongo test --eval "printjson(db.getCollectionNames())"

  连接运行在localhost上27017端口的mongod,并返回db.getCollectionNames()命令的输出

- 执行JavaScript文件
  可以指定一个.js文件让mongo shell执行,如下:

  $ mongo localhost:27017/test myjsfile.js

  连接运行在localhost上27017端口的mongod的test库,并执行myjsfile.js内的脚本

  当然,也可以在JavaScript脚本里使用Mongo()构造方法指定要连接的MongoDB实例

  也可以在mongo shell里使用load()方法执行一个.js文件,例如:

  > load("myjstest.js")

  该函数会导入并执行myjstest.js文件

  load()方法接受相对和绝对路径,如果mongo shell的当前工作目录是/data/db,myjstest.js位于/data/db/scripts目录,那么以下两种调用方法是相同的:

  > load("scripts/myjstest.js")
  > load("/data/db/scripts/myjstest.js")


== mongo shell里的数据类型 ==

MongoDB的BSON支持比JSON更多的数据类型,驱动对这些数据类型提供原生支持,mongo shell也提供多种帮助类以支持这些数据类型用于mongo JavaScript

【类型】

> 日期Date
  mongo shell提供多种方法返回日期,即可以是字符串也可以是日期对象:

  - Date()方法以字符串方式返回当前日期
  - new Date()构造函数使用ISODate()生成并返回一个Date对象
  - ISODate()同上

  在MongoDB内部,Date对象存储为64位有符号整数,其值为从Unix纪元(1970-01-01)开始的毫秒数,可表示的日期范围为纪元前后2亿9千万年

  以字符串返回日期,使用Date()方法,如下:

  var myDateString = Date();

  使用typeof操作符验证数据类型,返回值为string,如下:

  typeof myDateString

  也可使用new Date()或ISODate()构造函数,如下:

  var myDate = new Date();
  var myISODate = ISODate();
 
  使用 instanceof 操作符验证类型,返回值为true,如下:

  myDate instanceof Date
  myISODate instanceof Date

> ObjectId
  mongo shell提供ObjectId()包装类生成ObjectId数据类型,如下:

  new ObjectId

> 长数值NumberLong
  mongo shell默认将所有数值都作为浮点值处理,但提供了NumberLong()构造函数处理64位整数,其接受一个字符串型的大数值,如下:

  NumberLong("2090845886852")

  下例使用NumberLong()函数将数据写入集合:

  db.collection.insertOne( { _id: 10, calc: NumberLong("2090845886852") } )
  db.collection.updateOne( { _id: 10 }, { $set:  { calc: NumberLong("2555555000000") } } )
  db.collection.updateOne( { _id: 10 }, { $inc: { calc: NumberLong(5) } } )

  读取该文档,在返回的文档中,字段calc包含一个NumberLong对象:

  { "_id" : 10, "calc" : NumberLong("2555555000005") }

  如果使用$inc用普通浮点值去增长一个NumberLong字段的值,则会将数据类型改变为浮点型,如下例:

  1. 以浮点值5递增字段calc
     db.collection.updateOne( { _id: 10 }, { $inc: { calc: 5 } } )

  2. 读取数据,此时字段calc已是浮点型
     { "_id" : 10, "calc" : 2555555000010 }

> 整数NumberInt
  mongo shell默认将所有数值都作为浮点值处理,但提供了NumberInt()构造函数处理32位整数

> 小数NumberDecimal
  mongo shell默认将小数作为64位double值,但mongo shell提供NumberDecimal()构造函数生成128位的decimal值,以保证小数的精度正确

  以字符串型的decimal值通过NumberDecimal()构造函数创建小数:

  NumberDecimal("1000.55")

  NumberDecimal()构造函数也接受无引号的double值,但这是不推荐的,有丢失精度的危险,构造函数将十进制参数转换成二进制的double值,并扩展成或只保留15位数值(不包括小数点),例如:

  存储 NumberDecimal(1000.55),取到 NumberDecimal("1000.55000000000")
  存储 NumberDecimal(9999999.4999999999),取到 NumberDecimal("9999999.50000000")

  decimall数据类型从MongoDB 3.4才开始支持,如程序中要使用,要先确认驱动版本是否支持

> 比较和排序顺序
  在某集合中写入以下数据:

  { "_id" : 1, "val" : 9.99, "description" : "Double" }
  { "_id" : 2, "val" : 10, "description" : "Double" }
  { "_id" : 3, "val" : NumberLong(10), "description" : "Long" }
  { "_id" : 4, "val" : NumberDecimal( "9.99" ), "description" : "Decimal" }
  { "_id" : 5, "val" : NumberDecimal( "10.0" ), "description" : "Decimal" }

  使用db.numbers.find()方法以不同值查询该表,得到结果如下:

  No    Query                    Results
  --    ----------------------------------    ----------------------------------------------------------------------
  1.    { "val": 9.99 }                { "_id": 1, "val": 9.99, "description": "Double" }
  2.    { "val": NumberDecimal( "9.99" ) }    { "_id": 4, "val": NumberDecimal( "9.99" ), "description": "Decimal" }
  3.    { val: 10 }                { "_id": 2, "val": 10, "description": "Double" }
                          { "_id": 3, "val": NumberLong(10), "description": "Long" }
                          { "_id": 5, "val": NumberDecimal( "10.0" ), "description": "Decimal" }
  4.    { val: NumberDecimal( "10" ) }        { "_id": 2, "val": 10, "description": "Double" }
                          { "_id": 3, "val": NumberLong(10), "description": "Long" }
                          { "_id": 5, "val": NumberDecimal( "10.0" ), "description": "Decimal" }

  第一个查询 { "val": 9.99 } 匹配的是double型的9.99,而不是decimal型的
  第二个查询 { "val": NumberDecimal( "9.99" ) } 匹配的是decimal型的9.99,但不匹配double型的9.99,因为二者对于小数的精度表示能力不同,所以不相同
  第三和第四个查询是整数,所以double和decimal是相同的

> 检索decimal类型
  要查出类型为decimal的文档,使用$type操作符,如下:

  db.inventory.find( { price: { $type: "decimal" } } )

【检测数据类型】

要确定字段的类型,mongo shell提供了instanceof和typeof操作符

> instanceof
  返回布尔值表示该字段值是否为指定的类型,例如,以下操作检测_id字段是否为ObjectId类型:

  mydoc._id instanceof ObjectId

  返回值为true

> typeof
  返回待检测字段的数据类型,例如:

  typeof mydoc._id

  返回值为通用类型,不是具体类型,比如该例返回object而不是ObjectId


== mongo shell快速参考 ==

【命令历史】

可以在mongo shell里使用上下箭头键翻阅之前执行过的命令,历史命令存储在~/.dbshell文件里

【命令行选项】

mongo shell有庞杂的启动选项,以下列举一些常用的选项:

Option    说明
--help    查看所有mongo shell选项说明
--nodb    启动mongo shell时暂不连接实例和数据库
--shell    后接一个JavaScript文件,在启动了mongo shell后即执行

【命令帮助】

mongo shell提供多种帮助,以下列出最常用的帮助方法和命令:

序号    方法或命令        说明
  1.    help            显示帮助
  2.    db.help()        列出所有数据库的方法
  3.    db..help()    列出所有集合的方法,无论集合是否已存在
  4.    show dbs        列出该MongoDB实例上所有的数据库
  5.    use         切换当前数据库到,变量db被设置为当前库的引用
  6.    show collections    列出当前数据库里所有的集合
  7.    show users        列出当前数据库里所有的用户
  8.    show roles        列出当前数据库里所有的角色
  9.    show profile        打印出最新的5条slow操作
 10.    show databases        列出该MongoDB实例上所有的数据库,同show dbs
 11.    load()            执行一个JavaScript文件

【基础JavaScript操作】

在mongo shell里,变量db是当前数据库的引用,由于每次启动mongo shell时自动连接到test库,所以db变量也会自动设置为test,或使用 use 切换到指定数据库时,db变量也会设置为该库

mongo shell提供了很多数据库操作的API,以下列举一些常用操作:

序号    操作                描述
  1.    db.auth()            如果MongoDB实例开启认证,用于验证用户和密码
  2.    coll = db.        将当前数据库里指定集合的引号赋予变量coll,随后可以在coll上执行集合操作,例如coll.find();
  3.    db.collection.find()        查找集合中所有文档并返回一个游标
  4.    db.collection.insertOne()    写入一个新文档到集合
  5.    db.collection.insertMany()    写入多个新文档到集合
  6.    db.collection.updateOne()    更新集合中一个已存在的文档
  7.    db.collection.updateMany()    更新集合中多个已存在的文档
  8.    db.collection.save()        写入或更新一个文档
  9.    db.collection.deleteOne()    从集合中删除一个文档
 10.    db.collection.deleteMany()    从集合中删除多个文档
 11.    db.collection.drop()        移除整个集合
 12.    db.collection.createIndex()    创建一个集合上没有的索引,如果索引已存在则操作无效
 13.    db.getSiblingDB()        在同一连接里不切换当前数据库的情况下返回另一个数据库的引用

【查询】

在mongo shell里,使用find()和fineOne()方法执行查询操作

find()方法返回一个游标对象,mongo shell对其迭代以返回所有文档,mongo默认输出最先20个文档到屏幕,然后提示键入"it"继续输出后20个文档

下表给出一些mongo shell常用的查询操作:

序号    查询操作                    说明
  1.    db.collection.find()            查找集合中所有匹配条件的文档,如果未指定或为空(如{}),读操作选取集合中的所有文档,例如,选取users集合里name字段等于"Joe"的文档 db.users.find( { name: "Joe" } )
  2.    db.collection.find(, )    查找集合中所有匹配条件的文档,但只返回里指定的字段,_id字段总是被返回,除非显式指定为不返回,例如,从集合中选取所有文档,但只返回_id和name字段 db.users.find( { }, { name: true } )
  3.    db.collection.find().sort()        以指定排序方式返回所有文档,升序为1,降序为-1,例如,选取集合中所有文档,并以name字段升序返回 db.users.find().sort( { name: 1 } )
  4.    db.collection.find().sort()    以指定排序方式返回匹配条件的文档
  5.    db.collection.find().limit()        只返回条记录
  6.    db.collection.find().skip()        略过最先的条记录
  7.    db.collection.count()                返回集合中的文档数
  8.    db.collection.find().count()        返回集合中匹配条件的文档数
  9.    db.collection.findOne()            查找并返回一个匹配条件的文档,如果无匹配则返回null,内部实现方法就是find().limit(1),例如,从users集合中选取一个name字段为"Joe"的文档 db.users.findOne( { name: "Joe" } )

【错误检查方法】

2.6版本后,mongo shell的写入方法已经集成了写确认,无需单独执行db.getLastError()方法,因此,写入方法现在返回一个包含操作结果的WriteResult()对象,其中包括了写入错误和写入确认错误,而在之前的版本中,要使用db.getLastError()和db.getLastErrorObj()方法来返回错误信息

【管理命令帮助】

下表列出一些常用的数据库管理方法:

序号    管理方法                描述
  1.    db.cloneDatabase()        从指定的克隆当前数据库,数据库实例必须是无认证模式
  2.    db.copyDatabase(, , )    从克隆库到本机的库,数据库实例必须是无认证模式
  3.    db.fromColl.renameCollection()    将fromColl集合重命名为
  4.    db.repairDatabase()            修复和压缩当前数据库,该操作巨慢且开销大
  5.    db.getCollectionNames()            得到当前数据库中所有集合的名称列表
  6.    db.dropDatabase()            删除当前数据库

【打开额外的连接】

可以在mongo shell里创建新连接,下表列出创建连接的方法:

序号    连接创建方法                描述
  1.    db = connect("<:port>/")    打开一个新数据库连接
  2.    conn = new Mongo("<:port>")    使用new Mongo()打开一个到新服务器的连接
    db = conn.getDB("dbname")        使用getDB()方法为连接选取一个数据库

【其他】

序号    方法                描述
  1.    Object.bsonsize()    输出的BSON大小,单位字节(byte)

阅读(591) | 评论(0) | 转发(0) |
0

上一篇:MongoDB安装

下一篇:MongoDB CRUD 操作

给主人留下些什么吧!~~