走进MongoDB(三)---- 索引
在MongoDB中索引用于加速查询。没有索引,在查询时,Mongo会进行collection的全documents进行扫描,以匹配到满足查询条件的documents子集。如果建立合适的索引,使用索引进行查询可以极大减少扫描documetns的数量。
索引是一种特殊的数据结构,这种结构以一种易于访问的形式储存collection 数据的一笑部分。索引储存一个或几个指定的域的值,并按域的值进行排序。索引中值的排序支持对“=”匹配和基于范围的高效查询操作。
Default _id Index
在创建collection的时候,MongoDB会自动在_id域上创建唯一索引。_id上的索引是不能删除的。
Create an index
db.collection.createIndex();
mongoDBs索引使用b-tree数据结构。
Index Types
1.单字段索引
支持用户在单独的field上定义升序或降序索引。
对于单字段索引来说,索引排序顺序是升序还是降序都是一样的,因为mongodb可以沿着任一方向便利索引。
也可以在嵌入字段或嵌入文段上建立单字段索引。
2.混合索引
即在多个字段上建立索引。
混合索引中字段的顺序决定了索引结构中值的排列顺序。如:{ userid: 1, score: -1 },第一步、索引按照userid的值进行升序排序。第二步、索引按照score在userid值相同的区域内进行降序排序。
复合索引除了支持与所有索引字段匹配的查询外,还支持与索引字段前缀匹配的查询。即使用db.col.find({userid:’cc3’})也可以使用索引进行查询。
前缀
索引前缀是索引字段从头开始的子集,有
{ "item": 1, "location": 1, "stock": 1 }那么此索引字段的前缀是
{ item: 1 }、{ item: 1, location: 1 }
MongoDB可以在复合索引的前缀索引上使用索引查询。
3.多键索引
多键索引在数组的内容域上建立索引。
如何索引的字段是一个数组,那么mongodb会自动创建多键索引,不需要明确的指定多键索引类型。
限制
最多拥有一个值为数组的索引,如下collection:
{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }
创建{ a: 1, b: 1 }多键索引会出错
而在以下collection上创建多键索引则不会出错。
{ _id: 1, a: [1, 2], b: 1, category: "A array" }
{ _id: 2, a: 1, b: [1, 2], category: "B array" }
Shard key不能被指定为多键索引
哈希索引不能是多键所
不支持覆盖查询
4.地理空间索引
为了支持对地理空间坐标数据的索引。mongoDB提供了两个特定的索引:
2d indexes
使用二维几何学返回结果
2dsphere indexes
概览(基于version 2进行介绍)
Mongodb 2.6 开始支持2dsphere indexes version2,Mongodb3.2开始支持version3。
2d球面索引,使用球面几何学进行查询计算。MongoDB进行查询包含、交集和邻近等地理空间操作。
2dsphere indexes支持将数据存储为GeoJSON对象。
默认使用WGS84坐标系统进行计算。
2dshpere中增加的GeoJSON对象支持:multipoint、multiLineString、MultiPolygon和GeometryCollection。
地理索引不支持覆盖查询
geoNear和$geoNear限制
geoNear命令和$geoNear聚合管道要求collection最多只能拥有一个2dsphere 或2d 索引。这是因为geoNear命令和$geoNear聚合管道语法中都没有位置字段的选项,如果有多个2d索引,那么索引不知道选择并使用哪一个位置索引。
但是,地理查询操作符($near,$geoWithin)允许collection拥有多个2dsphere/2d索引,因为这些操作符中可以指定location字段。
Shard key 限制
不能将2dsphere索引指定为shard key。但是可以在分片集合的其它字段上指定地理索引。
2dsphere索引限制
2dsphere索引中一定要持有coordinate pairs 或者GeoJSON形式的几何数据。
2dsphere索引的创建
db.collection.createIndex( { <location field> : "2dsphere" } )
混合索引的创建
db.places.createIndex( { loc : "2dsphere" , category : -1, name: 1 } )
GeoJSON 对象
overview
在document中,使用type字段指定geojson的类型,使用coordinate字段指定geojson的坐标:{type:”<geotype>”,coordinate:<coordinates>},其中<coordinates>必须要使用固定的顺序:longitute, latitude。
Point(2.4)
指定geojson point : { type: "Point", coordinates: [ 40, 5 ] }
LineString(2.4)
指定geojson linestring: { type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }
polygon(2.4)
多边形由一个geojson 线性环形坐标数组组成。闭合的lineString至少包含四个点,第一个和最后一个点具有相同的坐标。
单环多边形(不能包含内部环)
{
type: "Polygon",
coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ]
}
多环多边形
--第一个环必须是外部环。
--内部环必须完全包含在外部环里面
--内部环之间不能相互重叠、交叉
{
type : "Polygon",
coordinates : [
[ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ],
[ [ 2 , 2 ] , [ 3 , 3 ] , [ 4 , 2 ] , [ 2 , 2 ] ]
]
}
MultiPoint多点(2.6)
{
type: "MultiPoint",
coordinates: [
[ -73.9580, 40.8003 ],
[ -73.9498, 40.7968 ],
[ -73.9737, 40.7648 ],
[ -73.9814, 40.7681 ]
]
}
MultiLineString多线段(2.6)
{
type: "MultiLineString",
coordinates: [
[ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ],
[ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ],
[ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ],
[ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ]
]
}
MultiPolygon多个多边形(2.6)
{
type: "MultiPolygon",
coordinates: [
[ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.9814, 40.7681 ], [ -73.958, 40.8003 ] ] ],
[ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.958, 40.8003 ] ] ]
]
}
GeometryCollection 几何集(2.6)
{
type: "GeometryCollection",
geometries: [
{
type: "MultiPoint",
coordinates: [
[ -73.9580, 40.8003 ],
[ -73.9498, 40.7968 ],
[ -73.9737, 40.7648 ],
[ -73.9814, 40.7681 ]
]
},
{
type: "MultiLineString",
coordinates: [
[ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ],
[ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ],
[ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ],
[ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ]
]
}
]
}
Sparse 属性
默认具有稀疏索引的属性(会忽略sparse :true option)。如果document没有2dshpere索引对应的字段,mongodb也不会将此document放在index里。
5.文本索引
用于在集合中搜索字符串文本
6.哈希索引
只支持等值匹配
索引属性
1.唯一索引
拒绝索引字段的重复值。
2局部索引
只对通过过滤条件的documents建立索引。通过partialFilterExpression选项来指定。(只对如所有score>50的记录建立索引)如:
db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
3.稀疏索引
使用Sparse选项控。稀疏索引会忽略不包含索引字段的document。
4.TTL索引
可以在一定时间后自动从集合中一处document的特殊索引。
索引的使用
索引就是用来提高读取操作的效率。
索引和比对规则
覆盖查询
当标准查询与投影查询仅仅包含索引字段的时候,MongDB会将结果直接从索引中返回,而不对collection进行扫描。
索引交点、交集
对于指定复合查询条件的查询,如果一个索引满足查询条件的一部分,另一个索引满足查询条件的另一部分,则MongoDB可以使用两个索引的交集完成查询。使用复合索引还是索引交点取决于具体的查询和系统。
在名称为orders的collection上常创建两个索引
{ qty: 1 }
{ item: 1 }
使用两个索引的交集进行查询:
db.orders.find( { item: "abc123", qty: { $gt: 15 } } )
限制
有一些用于索引的限制,例如:索引键的长度或每个集合的索引数。