关系

嵌入式关系
{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address": [
      {
         "building": "22 A, Indiana Apt",
         "pincode": 123456,
         "city": "Los Angeles",
         "state": "California"
      },
      {
         "building": "170 A, Acropolis Apt",
         "pincode": 456789,
         "city": "Chicago",
         "state": "Illinois"
      }]
}

以上数据保存在单一的文档中,可以比较容易的获取和维护数据。 你可以这样查询用户的地址:

>db.users.findOne({"name":"Tom Benzamin"},{"address":1})
注意:以上查询中 db 和 users 表示数据库和集合。

这种数据结构的缺点是,如果用户和用户地址在不断增加,数据量不断变大,会影响读写性能。

引用式关系
{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}

这种方法需要两次查询,第一次查询用户地址的对象id(ObjectId),第二次通过查询的id获取用户的详细地址信息。

>var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
>var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})
数据库引用

成员中有别的数据库里的数据
DBRef的形式:

{ $ref : , $id : , $db :  }

三个字段表示的意义为:

$ref:集合名称
$id:引用的id
$db:数据库名称,可选参数

DBRef的形式:

{ $ref : , $id : , $db :  }
三个字段表示的意义为:

$ref:集合名称
$id:引用的id
$db:数据库名称,可选参数

address DBRef 字段指定了引用的地址文档是在 runoob 数据库下的 address_home 集合,id 为 534009e4d852427820000002。

以下代码中,我们通过指定 $ref 参数(address_home 集合)来查找集合中指定id的用户地址信息:

>var user = db.users.findOne({"name":"Tom Benzamin"})
>var dbRef = user.address
>>db[dbRef.$ref].findOne({"_id":ObjectId(dbRef.$id)})

以上实例返回了 address_home 集合中的地址数据:

{
   "_id" : ObjectId("534009e4d852427820000002"),
   "building" : "22 A, Indiana Apt",
   "pincode" : 123456,
   "city" : "Los Angeles",
   "state" : "California"
}

覆盖索引查询

覆盖查询是以下的查询:

  • 所有的查询字段是索引的一部分
  • 所有的查询返回字段在同一个索引中

由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配查询条件和返回使用相同索引的查询结果。

因为索引存在于RAM中,从索引中获取数据比通过扫描文档读取数据要快得多。
我们在 users 集合中创建联合索引,字段为 gender 和 user_name :

>db.users.ensureIndex({gender:1,user_name:1})

现在,该索引会覆盖以下查询:

>db.users.find({gender:"M"},{user_name:1,_id:0})

查看索引性质

原子操作

对最小数据单元的操作
原子操作常用命令
$set
用来指定一个键并更新键值,若键不存在并创建。

{ $set : { field : value } }

$unset
用来删除一个键。

{ $unset : { field : 1} }

$inc
$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。

{ $inc : { field : value } }

$push
用法:

{ $push : { field : value } }

把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。

mongotemplate映射不到父类字段 mongodb 引用_数据push,只是一次可以追加多个值到一个数组字段内。

{ $pushAll : { field : value_array } }

$pull
从数组field内删除一个等于value值。

{ $pull : { field : _value } }

$addToSet
增加一个值到数组内,而且只有当这个值不在数组内才增加。

$pop
删除数组的第一个或最后一个元素

{ $pop : { field : 1 } }

$rename
修改字段名称

{ $rename : { old_field_name : new_field_name } }

$bit
位操作,integer类型

{$bit : { field : {and : 5}}}

ObjectId

ObjectId 是一个12字节 BSON 类型数据,有以下格式:

  • 前4个字节表示时间戳
  • 接下来的3个字节是机器标识码
  • 紧接的两个字节由进程id组成(PID)
  • 最后三个字节是随机数。

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

在一个集合里面,每个文档都有唯一的"_id"值,来确保集合里面每个文档都能被唯一标识。
使用以下代码生成新的ObjectId:

newObjectId = ObjectId()

你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:

>ObjectId("5349b4ddd2781d08c09890f4").getTimestamp()

以上代码将返回 ISO 格式的文档创建时间:

ISODate("2014-04-12T21:49:17Z")

在某些情况下,您可能需要将ObjectId转换为字符串格式。你可以使用下面的代码:

>new ObjectId().str