MongoDB的索引(三)
MongoDB的索引:
1. _id索引
该索引是大多数集合默认创建的索引,也就是说用户每插入一个数据,MongoDB会自动生成一条唯一的_id字段。
2. 单键索引
单键索引是最普通的索引,它不会自动创建,需要手动创建。
例如:dm.bochao_collection.ensureIndex({name:"zhangsan"})
创建了一个name=zhangsan的索引
> db.bochao_collection.ensureIndex({x:11}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.bochao_collection.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "bochao.bochao_collection" }, { "v" : 1, "key" : { "x" : 11 }, "name" : "x_11", "ns" : "bochao.bochao_collection" } ]
3. 多键索引
多键索引与单键索引类似,区别在于字段的值。
单键索引:值为一个单一的值,例如字符串,数字或者日期。
多键索引: 值具有多个记录,例如数组。
4. 复合索引
当使用多个查询条件时候,可以创建复合索引。
> db.bochao_collection.ensureIndex({x:11,y:22}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } > db.bochao_collection.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "bochao.bochao_collection" }, { "v" : 1, "key" : { "x" : 11 }, "name" : "x_11", "ns" : "bochao.bochao_collection" }, { "v" : 1, "key" : { "x" : 11, "y" : 22 }, "name" : "x_11_y_22", "ns" : "bochao.bochao_collection" } ]
5. 过期索引
过期索引是在一定的时间会自动过期失效的索引
在索引过期后,相应的数据会被自动删除
这将比较适合存储一些在一段时间后会失效的数据,如用户登录信息、日志信息等等
注意:
<1>. 存储在过期索引的字段值类型必须是时间类型,必须是ISODate或者是ISO数组,不能使用时间戳,否则不能自动清除数据。
> db.bochao_collection.ensureIndex({time:1},{expireAfterSeconds:30})
db.bochao_collection.insert({time:new Date(), address:"北京市昌平区"})
这会在30秒钟后自动删除该条数据
<2>. 如果指定了ISODate数组,则按照最小的时间进行删除。也就是说如果有一个最小的时间到达了,则删除该条数据。
<3>. 过期索引不能创建复合索引
<4>. 索引过期按指定时间删除是不精确的。 因为删除过程是后台进程每60S执行一次,有误差
6. 全文索引
对字符串与字符串数组创建全文可搜索的索引
<1>. 创建全文索引
> db.bochao_collection.ensureIndex({article:"text"}) { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
<2>. 使用全文索引查询
> db.bochao_collection.find({$text:{$search:"aa"}}) { "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" } { "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" } { "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }
MongoDB的一个集合中只能创建一个全文索引
# 查询包含多个条件字符串(或的关系),如下:
> db.bochao_collection.find({$text:{$search:"aa bb cc"}}) { "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" } { "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" } { "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }
# 查询包含多个条件字符串(与的关系),如下:
> db.bochao_collection.find({$text:{$search:"\"aa\", \"bb\", \"cc\""}}) { "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" }
# 按照条件全文检索并且不包含某个字符的查询,如下
> db.bochao_collection.find({$text:{$search:"aa bb -cc"}}) { "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" } { "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" }
# 全文索引的相似度,使用这样的语法: score:{$meta:"textScore"}
写在查询条件之后可以返回结果的相似度,与sort一起使用,可以达到很好的使用效果。
> db.bochao_collection.find({$text:{$search:"aa bb"}}) { "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd" } { "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg" } { "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee" } { "_id" : ObjectId("55da00670a78029813da6fcc"), "article" : "aa bb" } > db.bochao_collection.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}) { "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd", "score" : 1.25 } { "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg", "score" : 1.25 } { "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee", "score" : 1.25 } { "_id" : ObjectId("55da00670a78029813da6fcc"), "article" : "aa bb", "score" : 1.5 } > db.bochao_collection.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) { "_id" : ObjectId("55da00670a78029813da6fcc"), "article" : "aa bb", "score" : 1.5 } { "_id" : ObjectId("55d9fb263b6af5422bb1ed52"), "article" : "aa bb cc dd", "score" : 1.25 } { "_id" : ObjectId("55d9fb2e3b6af5422bb1ed53"), "article" : "aa bb ff gg", "score" : 1.25 } { "_id" : ObjectId("55d9fb413b6af5422bb1ed54"), "article" : "aa bb hh ee", "score" : 1.25 }
利用这个功能可以实现一个不错的全文检索功能哦
注意:
每次查询,只能使用$text查询
$text查询不能出现在$nor查询中
查询中如果包含了$text,hint将失效
全文索引不支持中文
# 索引的重要属性:
<1>. 索引的名称:自定义索引的名称
> db.bochao_collection.ensureIndex({dcz:1000}, {name:"dczIndex"}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 4, "numIndexesAfter" : 5, "ok" : 1
{ "v" : 1, "key" : { "dcz" : 1000 }, "name" : "dczIndex", "ns" : "bochao.bochao_collection" }
删除索引:
> db.bochao_collection.dropIndex("dczIndex") { "nIndexesWas" : 5, "ok" : 1 }
<2>. 索引的唯一性,unique指定
> db.bochao_c.ensureIndex({m:1,n:1},{unique:true}) { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
这样创建后就不能插入两条一样的M,N数据了。
<3>. 稀疏索引,使用sparse关键字:
避免为不必要的字段上创建索引,创建语法是:db.collection.ensureIndex({},{sparse:true/false})
> db.bochao3.ensureIndex({m:1},{sparse:true}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
7. 地址位置索引
将一些点的位置存储在MongoDB 中,创建索引后,可以按照位置来查找其他点。
子分类:
2d索引:用于存储和查找平面上的点
2dsphere索引:用于存储和查找球面上的点
查找方式:
1. 查找距离某个点一定距离内的点
2. 查找包含在某区域内的点
# 创建2d索引
创建语法:db.collection.ensureIndex({w:"2d"})
2d位置表示方法:经纬度[经度,纬度],取值范围:经度[-180,180] 纬度[-90,90]
查询方式:
1. $near查询:查询距离某个点最近的点:
插入几个平面坐标(经纬度):
> db.location.insert({w:[30,60]}) WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[1,2]}) WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[30,80]}) WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[180,40]}) WriteResult({ "nInserted" : 1 }) > db.location.insert({w:[127,20]}) WriteResult({ "nInserted" : 1 })
查询一下: > db.location.find() { "_id" : ObjectId("55db2ce6a0319a75b8c83ba1"), "w" : [ 30, 60 ] } { "_id" : ObjectId("55db2cf5a0319a75b8c83ba2"), "w" : [ 1, 2 ] } { "_id" : ObjectId("55db2d01a0319a75b8c83ba3"), "w" : [ 30, 80 ] } { "_id" : ObjectId("55db2d0ba0319a75b8c83ba4"), "w" : [ 180, 40 ] } { "_id" : ObjectId("55db2d13a0319a75b8c83ba5"), "w" : [ 127, 20 ] }
查询距离经纬度[1,1]最近的,看到会返回了全部坐标点,MongoDB默认会返回100个最近的点 > db.location.find({w:{$near:[1,1]}}) { "_id" : ObjectId("55db2cf5a0319a75b8c83ba2"), "w" : [ 1, 2 ] } { "_id" : ObjectId("55db2ce6a0319a75b8c83ba1"), "w" : [ 30, 60 ] } { "_id" : ObjectId("55db2d01a0319a75b8c83ba3"), "w" : [ 30, 80 ] } { "_id" : ObjectId("55db2d13a0319a75b8c83ba5"), "w" : [ 127, 20 ] } { "_id" : ObjectId("55db2d0ba0319a75b8c83ba4"), "w" : [ 180, 40 ] } 可以使用$maxDistance关键字来做限制 > db.location.find({w:{$near:[1,1], $maxDistance:80}}) { "_id" : ObjectId("55db2cf5a0319a75b8c83ba2"), "w" : [ 1, 2 ] } { "_id" : ObjectId("55db2ce6a0319a75b8c83ba1"), "w" : [ 30, 60 ] }
2. 使用$geoWithin查询:查询某个形状内的点
形状的表示:
<1>. $box:矩形,使用{$box:[[<x1>,<y1>],[<x2>,<y2>]]}表示
> db.location.find({w:{$geoWithin:{$box:[[10,20],[80,80]]}}}) { "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] } { "_id" : ObjectId("55df169ac7913b1f63dd27e4"), "w" : [ 10, 30 ] } { "_id" : ObjectId("55df16a3c7913b1f63dd27e5"), "w" : [ 20, 30 ] } { "_id" : ObjectId("55df16c1c7913b1f63dd27eb"), "w" : [ 10, 60 ] } { "_id" : ObjectId("55df16a6c7913b1f63dd27e6"), "w" : [ 20, 50 ] } { "_id" : ObjectId("55df16aac7913b1f63dd27e7"), "w" : [ 50, 50 ] } { "_id" : ObjectId("55df16afc7913b1f63dd27e8"), "w" : [ 50, 80 ] }
<2>. $center:圆形,使用{$center:[[<x1>,<y1>],r]}表示
> db.location.find({w:{$geoWithin:{$center:[[10,20],40]}}}) { "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] } { "_id" : ObjectId("55df169ac7913b1f63dd27e4"), "w" : [ 10, 30 ] } { "_id" : ObjectId("55df16a3c7913b1f63dd27e5"), "w" : [ 20, 30 ] } { "_id" : ObjectId("55df16c1c7913b1f63dd27eb"), "w" : [ 10, 60 ] } { "_id" : ObjectId("55df16a6c7913b1f63dd27e6"), "w" : [ 20, 50 ] }
<3>. $polygon:多边形,使用{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}表示
> db.location.find({w:{$geoWithin:{$polygon:[[10,20],[40,30],[90,30]]}}}) { "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] }
<4>. geoNear查询:geoNear使用runCommand命令进行使用,如下:
db.runCommand({geoNear:<collection>,
near:[x,y],
minDistance:, (对2d索引无效)
maxDistance:,
num:
...})
> db.runCommand({geoNear:"location",near:[10,20],maxDistance:10,num:2}) { "results" : [ { "dis" : 0, "obj" : { "_id" : ObjectId("55df1696c7913b1f63dd27e3"), "w" : [ 10, 20 ] } }, { "dis" : 10, "obj" : { "_id" : ObjectId("55df169ac7913b1f63dd27e4"), "w" : [ 10, 30 ] } } ], "stats" : { "nscanned" : 22, "objectsLoaded" : 2, "avgDistance" : 5, "maxDistance" : 10, "time" : 4 }, "ok" : 1
# 创建2dsphere索引
创建方式:db.collection.ensureIndex({w:"2dsphere"})
位置表示方式
GeoJSON:描述一个点,一条直线,多边形等形状。
格式:{type:"", coordinates:[<coordinates>]}
查询方式与2d索引方式类似,支持$minDistance与$maxDistance