MongoDB入门下

1.使用shell的技巧

shell内置的帮助:

使用db.help()可以查看数据库级别的命令帮助,集合的相关帮助可以通过db.blog.help()

输入的时候不要输入括号,这样就可以显示该函数的javascript源代码:

 

使用db.集合名 的方式来访问集合一般不会有问题,但如果集合名恰好是数据库类的一个属性,这样会有问题,例如:

要访问version这个集合,使用db.version是不行的,因为db.version是个数据库函数.

当javascript只有在db中找不到指定的属性时,才会将其作为集合返回.当有属性与目标集合同名时,可以使用

getCollection函数,如:db.getCollection("version")

要查看名称中含有无效的javascript字符的集合,如:db.blog-refactor是个有效的集合名,但在javascript中就变成了

变量相减.通过db.getCollection("blog-refactor")可以得到blog-refactor集合.

在javascript中,x.y和x['y']是等价的.

var collections={"posts","comments","authors"};

for(i in collections)

{

  doStuff(db.blog[collections[i]])

}

而不是写成这样:

doStuff(db.blog.posts)

doStuff(db.blog.comments)

doStuff(db.blog.authors)

 

2.数据类型

基本的数据类型

MongoDB的文档类似于JSON.在概念上与javascript中的对象相似.

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

1.null

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

{"x":null}

2.布尔值

true或false

{"x":false}

3.32位整数

shell中这个类型不适用,因为javascript只支持64位浮点数,所以32位整数会被自动转换

4.64位整数

shell中这个类型不适用,shell会使用一个特殊的内嵌文档来显示64位整数

5.64位浮点数

shell中的数字都是这种类型,下面都是浮点数

{"x":3.14}

{"x":3}

6.字符串

utf-8字符串都可表示为字符串类型的数据

{"x":"Refactor"}

7.符号

shell中这个类型不适用.shell将数据库里的符号类型转换成字符串

8.对象id

对象id是文档的12字节的唯一ID

{"x":ObjectId()}

9.日期

日期类型存储的是从标准纪元开始的毫秒数.不存储时区

{"x":new Date()}

10.正则表达式

文档中可以包含正则表达式,采用javascript语法

{"x":/refactor/i}

11.代码

文档中可以包含javascript代码

{"x":function(){....}}

12.二进制数据

二进制数据由任意字节的串组成,shell中不能用

13.最大值

BSON包含的特殊类型,表示可能的最大值,shell中不能用

14.最小值

BSON包含的特殊类型,表示可能的最小值,shell中不能用

15.未定义

文档中可以使用未定义类型

{"x":undefined}

16.数组

值的集合或列表可以表示成数组

{"x":["a","b","c"]}

17.内嵌文档

文档中可以包含别的文档,也可以作为值嵌入到父文档中

{"x":{"hello":"world"}}

 

数字类型

javascript中只有一个"数字"类型.MongoDB中有3种数字类型(32位整数,64位整数,64位浮点数),

shell必须绕过javascript的限制.默认情况下,shell中的数字都被MongoDB当成双精度数.这就意味着

如果你从数据库中获得的是一个32位整数,修改文档后,将文档存回到数据库的时候,这个整数就被转换成了

浮点数,即便是保持这个整数不修改,也会转换为浮点数.所以不应该子啊shell下覆盖整个文档.

 

数字只能表示为双精度数(64位浮点数)的另外一个问题是:有些64位整数并不能表示为64为浮点数,所以要存入

一个64位整数,在shell中查看,它会表示为一个内嵌文档,表示可能不准确.

 

日期类型

在javascript中,Date对象用作MongoDB的日期类型,创建一个新的Date对象,通常会调用new Date(),而不是 Date()

调用构造函数(不包括new)实际会返回对日期的字符串表示,而不是真正的Date对象,这是javaScript本身的特性.

shell中的日期显示时使用本地时区设置.但是,日期在数据中是从标准纪元开始的毫秒数的形式存储的,没有与之相关的时区信息

 

数组类型

数组是一组值,既可以作为有序对象(如:列表,栈或队列)来操作,也可以作为无序对象(如:集合)操作.

如:{"things":["pie",3.14]}

诉诸数组可以包含不同数据类型的元素(这个例子中是一个字符串和一个浮点数),实际上,常规键值对支持的值都可以

作为数组的元素,甚至是嵌套的数组

MongoDB可以查询所有"things"数组中还有3.14的文档,要是经常使用这个查询,可以对"things"创建索引,来提高性能

MongoDB可以使用原子更新修改数组中的内容,比如深入数组内部将pie改为pi.

 

内嵌文档类型

内嵌文档就是把整个MongoDB文档作为另一个文档中键的一个值.这样数据可以组织的更自然,不用非得存成扁平结构.

如:应一个文档来表示一个人,同时还要保存他的地址,可以将地址内嵌到文档中

peopleAddress=
{
  "name":"Refactor",
  "address":
  {
    "street":"wuzhong",
    "city":"suzhou"
  }
}

同数组一样,MongoDB能够理解内嵌文档的结构,并能深入其中 构建索引,执行查询或更新.

内嵌文档可以改变处理数据的方式,在关系型数据库中,之前的文档一般会拆分成两个表("people"和"address")

中的两个行.在MongoDB中,可以将地址文档直接嵌入到人员文档中.这样也有坏处,因为MongoDB会存储很多

的重复数据,如果在关系型数据库中"address"在一个独立的表中,要修改地址中的拼写错误.当我们对"address"表

进行修改后,那么每一个使用这个地址的人的信息都会得到更新.但在MongoDB中,则需要在每个人的文档中修改拼写错误

 

_id和ObjectId

MongoDB中存储的文档必须有一个"_id"键.这个键的值可以是任何类型,默认是ObjectId对象.

在一个集合里面,每个文档都有唯一的"_id"值,来确保集合里面每个文档都能唯一的标识.如果有

两个集合的话,两个集合可以都有一个值为123的"_id"键,但是每个集合里面只能有一个"_id"是123的文档

ObjectId是"_id"的默认类型,ObjectId可以确保分布式数据的唯一性

如果在插入文档的时候没有"_id"键,系统会自动帮你创建一个.可以由MongoDB服务器来做这件事情,

但通常会在客户端驱动程序完成,理由如下:

1.虽然ObjectId设计成轻量型的,易于生成的,但毕竟的生成的时候还是会产生开销.在客户端生成体现了

MongoDB的设计理念:能从服务端转移到驱动程序来做的就尽量转移.这种理念的原因是:扩展应用层比

扩展数据库层容易的多,将事务交由客户端处理,就减轻了数据库扩展的负担.

2.在客户端生成ObjectId,驱动程序能够提供更丰富的API.如驱动程序可以有自己的insert方法,可以返回生成

的ObjectId,也可以直接将其插入文档.如果驱动程序允许服务器生成ObjectId,那么将需要单独的查询,以确定

插入的文档中的"_id"值. 

 

posted on 2012-07-25 09:19  refactor  阅读(5491)  评论(3编辑  收藏  举报

导航