上一篇文章中我们讨论了:mongodb覆盖查询、分析查询和原子操作,下面开始讨论mongodb的高级索引、对索引的限制以及了解ObjectId的结构。
一、高级索引
考虑以下用户集合的文档:
{
"address": {
"city": "Naplas",
"state": "Italino",
"pincode": "321"
},
"tags": [
"music",
"art",
"story"
],
"name": "Van"
}
上面的文档包含一个地址子文档和一个标记数组。
1、索引数组字段
假设我们希望基于用户的标记tag搜索用户文档,我们需要在集合中的tags数组上创建一个索引。
在数组上创建一个索引,然后为它的每个字段创建单独的索引项。所以在我们的例子中,当我们在tags数组上创建一个索引时,将为它的值music、art和story创建单独的索引。
要在标记tag数组上创建索引,请使用以下代码:
db.users.ensureIndex({"tags":1})
创建索引之后,我们可以像这样搜索集合的tags字段:
db.users.find({tags:"philosophy"})
要验证是否使用了正确的索引,请使用下面的explain命令:
db.users.find({tags:"art"}).explain()
2、索引子文档字段
假设我们希望根据城市、识别码等字段搜索文档。由于所有这些字段都是address子文档字段的一部分,所以我们将在子文档的所有字段上创建一个索引。
要在子文档的所有三个字段上创建索引,请使用以下代码:
db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
创建索引之后,我们可以使用该索引搜索任何子文档字段,如下所示:
db.users.find({"address.city":"Naples"})
记住查询表达式必须遵循指定索引的顺序,因而上面创建的索引将支持以下查询:
db.users.find({"address.city":"a","address.state":"A"})
它还将支持以下查询:
db.users.find({"address.city":"a","address.state":"A","address.pincode":"963"})
二、限制索引
额外的开销
每个索引都会占用一些空间,并在每次插入、更新和删除时造成开销。因此如果你很少将集合用于读取操作,那么不使用索引是有意义的。
RAM的消耗
索引存储在RAM里面应确保索引的大小不会超过RAM的限制,若索引大小增加了RAM大小,mongodb会删除一些索引从而导致性能损失。
查询限制
索引不能用于使用下面情况的查询:
- 正则表达式或否定运算符,如$nin、$not等。
- 算术运算符,比如$mod等等。
- $where子句
因此始终建议检查查询的索引使用情况。
索引键限制
从2.6版本开始,如果现有索引字段的值超过索引键限制,MongoDB将不会创建索引。
插入超过索引键限制的文档
如果文档的索引字段值超过索引键限制,MongoDB将不会向索引集合插入任何文档,mongorestore和mongoimport实用程序也是如此。
最大范围内
- 一个集合不能有超过64个索引。
- 索引名的长度不能超过125个字符。
- 一个复合索引最多可以索引31个字段。
三、ObjectId的结构
在前面的所有内容中我们都使用了MongoDB对象Id,在本内容中我们将了解ObjectId的结构。
ObjectId是一个12字节的BSON类型,具有以下结构
- 前4个字节表示自unix标准时间以来的秒数
- 接下来的3个字节是机器标识符
- 接下来的2个字节由进程id组成
- 最后3个字节是一个随机计数器值
MongoDB使用ObjectIds作为每个文档的_id字段的默认值,它是在创建任何文档时生成的,ObjectId的复杂组合使得所有_id字段都是惟一的。
1、创建一个新的ObjectId
要生成新的ObjectId,请使用以下代码:
newObjectId = ObjectId()
上面的语句返回了惟一生成的id,你还可以自定义提供一个12字节的id,而不是生成MongoDB的ObjectId。
2、创建文档的时间戳
由于_id ObjectId在缺省情况下存储4字节的时间戳,因此在大多数情况下不需要存储任何文档的创建时间。可以使用getTimestamp方法获取文档的创建时间,这将以ISO日期格式返回此文档的创建时间。
ObjectId("ID").getTimestamp()
3、将ObjectId转换为字符串
在某些情况下,可能需要字符串格式的ObjectId值,要转换字符串中的ObjectId,请使用以下代码,下面代码将返回Guid格式的字符串。
newObjectId.str
评论前必须登录!
注册