mongodb指南(翻译)(十八) - developer zone - 索引(二)_id索引、复合索引、稀疏索引、数组索引、唯一索引
_id索引
除了定容量集合外的所有集合,都会自动为_id字段创建一个索引。这是一个特殊索引并且不能被删除。该_id索引强制它的关键字都是唯一的(除了分片环境下的一些情景)。
_id值是恒定不变的。
对内嵌关键字进行索引(“点表示法”)
在Mongodb中,你可以对内嵌文档的关键字进行索引。访问子文档的方法被视为点表示法。例如:
db.things.ensureIndex({"address.city": 1})
文档作为关键字
被索引的字段可以是任意类型,包括(内嵌的)文档:
db.factories.insert( { name: "xyz", metro: { city: "New York", state: "NY" } } );
db.factories.ensureIndex( { metro : 1 } );
// this query can use the above index:
db.factories.find( { metro: { city: "New York", state: "NY" } } );
// this one too, as {city:"New York"} < {city:"New York",state:"NY"}
db.factories.find( { metro: { $gte : { city: "New York" } } } );
// this query does not match the document because the order of fields is significant
db.factories.find( { metro: { state: "NY" , city: "New York" } } );
将文档作为关键字的替代方法是建立一个组合索引:
db.factories.ensureIndex( { "metro.city" : 1, "metro.state" : 1 } );
// these queries can use the above index:
db.factories.find( { "metro.city" : "New York", "metro.state" : "NY" } );
db.factories.find( { "metro.city" : "New York" } );
db.factories.find().sort( { "metro.city" : 1, "metro.state" : 1 } );
db.factories.find().sort( { "metro.city" : 1 } )
这两种方法各有优缺点。当使用整个(子)文档作为一个关键字,比较顺序是预定义的并且是以关键字在BSON文档出现的升序来排序的。在组合索引中,你可以混合升序和降序的关键字,查询优化器还是可以只使用索引中的第一个关键字进行查询。
组合索引
除了基本的单个关键字索引外,Mongodb还支持多建“组合”索引。正如基本索引那样,你可以在shell中使用ensureIndex()来创建组合索引,但不像基本索引仅可以指定一个关键字,此时你可以指定多个:
db.things.ensureIndex({j:1, name:-1});
当创建一个索引时,关键字后面的数字指定了索引排序的方向,因此它只能是1(升序)或者-1(降序)。对于单键索引或者随机访问来说方向并不重要,但是当你对组合索引做排序或者范围查询时,方向就很重要了。
如果你有一个建立在多字段上的组合索引,你可以使用它查询多键前面的子集字段。因此如果你有一个索引在:
a,b,c
你可以使用它对这些字段进行查询:
a
a,b
a,b,c
对数组内元素进行索引
如果文档中要建立索引的字段是是一个数组,Mongodb会为数组中每一个元素建立索引。请移步多建章节查看详细内容。
稀疏索引
“稀疏索引”就是仅包含有被索引字段的文档的索引。
任何没有稀疏索引字段的文档都不会被存储到该索引中;这种索引就是由于不包含没有索引字段的文档而被称为稀疏索引的。
根据定义,稀疏索引并不完整(对该集合而言)并且与完整索引表现不同。当使用“稀疏索引”进行排序(或者是过滤),集合中的一些文档可能不会返回。这是因为只有该集合中的文档会返回。
> db.people.ensureIndex({title : 1}, {sparse : true})
> db.people.save({name:"Jim"})
> db.people.save({name:"Sarah", title:"Princess"})
> db.people.find()
{ "_id" : ObjectId("4de6abd5da558a49fc5eef29"), "name" : "Jim" }
{ "_id" : ObjectId("4de6abdbda558a49fc5eef2a"), "name" : "Sarah", "title" : "Princess" }
> db.people.find().sort({title:1}) // only 1 doc returned because sparse
{ "_id" : ObjectId("4de6abdbda558a49fc5eef2a"), "name" : "Sarah", "title" : "Princess" }
> db.people.dropIndex({title : 1})
{ "nIndexesWas" : 2, "ok" : 1 }
> db.people.find().sort({title:1}) // no more index, returns all documents
{ "_id" : ObjectId("4de6abd5da558a49fc5eef29"), "name" : "Jim" }
{ "_id" : ObjectId("4de6abdbda558a49fc5eef2a"), "name" : "Sarah", "title" : "Princess" }
你可以将稀疏和唯一联合起来创建唯一约束从而忽略掉没有对应字段的文档。
注意Mongodb的稀疏索引不是阻塞型索引。Mongodb稀疏索引可以被认为是指定过滤器的稠密索引。
唯一索引
Mongodb支持唯一索引,它保证跟已有文档的索引关键字重复的文档不会被插入。创建保证不会有两个文档在字段firstname和lastname上有重复值,你可以这样做:
db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
唯一索引和不存在的关键字
当保存到集合中的文档在索引字段没有值的话,它的索引字段会被赋值为null然后插入。就是说,你不可能在唯一索引中插入多个在某个索引字段都没有值的文档。
db.things.ensureIndex({firstname: 1}, {unique: true});
db.things.save({lastname: "Smith"});
// Next operation will fail because of the unique index on firstname.
db.things.save({lastname: "Jones"});
dropDups
如果在某个字段已经存在重复值,那么将不能在该字段建立唯一索引。如果无论如何你都要建立唯一索引,并且仅保留数据库中在该字段第一个出现的文档然后删除所有在该字段有重复值的文档,请增加“dropDups”选项:
db.things.ensureIndex({firstname : 1}, {unique : true, dropDups : true})
posted on 2011-12-19 16:37 xinghebuluo 阅读(2757) 评论(0) 编辑 收藏 举报