索引类型
唯一索引
唯一索引可以确保集合的每一个文档的指定建都有唯一值。例如:如果想保证不同文档的username键拥有不同的值,创建一个唯一索引就好了。
db.users.getIndexes() // 查看所有索引
> db.users.dropIndex("username_1")//删除之前建立的索引
{ "nIndexesWas" : 3, "ok" : 1 }
db.users,createIndex({"username":1},{"unique":true})//建立唯一索引
如果集合中你要建立唯一索引的键的已经存在重复的值,那么执行上面的命令时就会报错
> db.users.createIndex({"username":1},{"unique":true})
{
"ok" : 0,
"errmsg" : "E11000 duplicate key error collection: test.users index: username_1 dup key: { : \"bob\" }",
"code" : 11000,
"codeName" : "DuplicateKey"
}
为了测试我们把重复的删除再继续
> db.users.remove({"username":"bob"})
WriteResult({ "nRemoved" : 4 })
> db.users.createIndex({"username":1},{"unique":true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
> db.users.insert({"username":"bob"})
WriteResult({ "nInserted" : 1 })
> db.users.insert({"username":"bob"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.users index: username_1 dup key: { : \"bob\" }"
}
})
在username上创建唯一索引后,当我们再插入相当的值时,此时就会报错。另外,mongo自动生成的_id就会自动建立唯一索引,唯一不同的是这个索引不能被删除。注:如果一个文档没有对应的键,索引会将其作为null存储,所以如果对某个键建立了唯一索引,但插入了多个缺少该索引键的文档,会由于集合已经存在一个该索引键的值为奴冷冷的文档而导致插入失败。有些情况下,一个值可能无法被索引,索引储桶的大小是有限制的,如果某个索引条目超出了它的限制,那么这个条目就不会包含在索引里。每条索引的key不得超过1024个字节,如果index key的长度超过此值,将会导致write操作失败。
超出8KB大小的键不会受到唯一索引的约束,即可以插入多个同样的8KB长的字符串。
复合唯一索引
也可以创建复合的唯一索引。插入时单个键的值可以相同,但所有键的组合值必须是唯一的。GirdFS是mongo中存储大文件
的标准方式,其中就用到了复合唯一索引。
稀疏索引
前面讲过唯一索引会把null看做值,所以无法将多个缺少唯一索引中的键的文档插入到集合中。这时我们希望唯一索引只对包含相应键的文档生效,如果有一个可能存在也可能不存在的字段,但是当它存在时,它必须是唯一的,这时就可以将unique与sparse选项组合在一起使用。mongo中的稀疏索引与关系数据库中的稀疏索引是完全不同的概念,基本上来说,mongo中的稀疏索引只是不需要将每个文档都作为索引条目。
db.createIndex({"email":1}, {"unique":true,"sparse":true})
稀疏索引不必是唯一的,只要去掉unique选项,就可以创建一个非唯一的稀疏索引。