插入准备数据
> for(var i=1;i<10;i++) { db.user2_collection.insert({name:i}) } WriteResult({ "nInserted" : 1 }) > db.user2_collection.find() { "_id" : ObjectId("55f69331cc1593a1bb113958"), "name" : 1 } { "_id" : ObjectId("55f69331cc1593a1bb113959"), "name" : 2 } { "_id" : ObjectId("55f69331cc1593a1bb11395a"), "name" : 3 } { "_id" : ObjectId("55f69331cc1593a1bb11395b"), "name" : 4 } { "_id" : ObjectId("55f69331cc1593a1bb11395c"), "name" : 5 } { "_id" : ObjectId("55f69331cc1593a1bb11395d"), "name" : 6 } { "_id" : ObjectId("55f69331cc1593a1bb11395e"), "name" : 7 } { "_id" : ObjectId("55f69331cc1593a1bb11395f"), "name" : 8 } { "_id" : ObjectId("55f69331cc1593a1bb113960"), "name" : 9 }
一、索引的种类
创建格式:db.集合名.ensureIndex({params},{params})
其中第二个参数是索引的属性,如:名字{name:"索引名称"} 唯一性{unique:true/false} 稀疏性{sparse:true/false} 是否定时删除{expireAfterSeconds:秒数}
唯一性是指创建了唯一索引的字段的值不能重复
稀疏性是指一个集合中的每条文档的字段不是完全相同的,例如:在字段A上创建了{sparse:false}的索引,那么不管集合中的文档是否拥有字段A,mongodb都会维护索引
1._id索引(主键索引吧) _id索引是绝大多数集合默认建立的唯一索引
查看索引
> db.user2_collection.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.user2_collection" } ]
2.普通索引
> db.user2_collection.insert({name:[1,2,3,4,5]})> db.user2_collection.ensureIndex({name:1},{name:"normal_index"}) //如果name的值是单个值,则mongodb会创建单键索引 如果是多个值则创建多键索引 1 表示asc排序 -1 表示desc排序 { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.user2_collection.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.user2_collection" }, { "v" : 1, "key" : { "name" : 1 }, "name" : "normal_index", "ns" : "test.user2_collection" } ]
3.复合索引 当我们的查询条件不是只有一个时,就需要建立复合索引
> db.user2_collection.ensureIndex({name:1,age:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } > db.user2_collection.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.user2_collection" }, { "v" : 1, "key" : { "name" : 1 }, "name" : "name_1", "ns" : "test.user2_collection" }, { "v" : 1, "key" : { "name" : 1, "age" : 1 }, "name" : "name_1_age_1", "ns" : "test.user2_collection" } ]
4.过期索引 在一段时间后会过期失效的索引 索引过期后相应的数据会被删除
注意:
a、存储过期索引字段的值必须是 ISODate 型 或 ISODate 数组型 否则数据不会被自动删除
b、如果是数组型 则按最小的 ISODate 进行计算过期时间
c、过期索引必须是普通索引(单键索引或多键索引)
d、删除是由mongodb每60s跑一次的进程进行删除的,所以有一定的误差的,即过期时间到了,但是程序还没跑,那么数据也不会立即删除
> db.user2_collection.insert({name:new Date(),hehe:1}) > db.user2_collection.find() > db.user2_collection.ensureIndex({name:2},{expireAfterSeconds:10}) //创建一个十秒后过期的索引 > db.user2_collection.getIndexes() > db.user2_collection.insert({name:new Date(),hehe:2}) > db.user2_collection.find()
5.全文索引 一个集合只允许有一个全文索引
全文索引限制:
a.每次查询只能指定一个$text
b.$text查询不能出现在$nor查询中
c.查询中如果包含了$text,hint不再起作用
d.mongodb的全文索引不支持中文
> db.user3_collection.insert({name:"a"}) //准备数据
> db.user3_collection.insert({name:"a b"})> db.user3_collection.insert({name:"a b c"})
> db.user3_collection.insert({name:"a b c d"})> db.user3_collection.ensureIndex({name:"text"}) //单键创建全文索引 多键则是 {key_1:"text",key_2:"text"} 全部键则是 {"$**":"text"} > db.user3_collection.find({$text:{$search:"a"}}) //查询包含 a 的记录 返回结果为空 不知道为什么
> db.user3_collection.find({$text:{$search:"a b"}}) //查询包含 a 或 b 的记录 有结果返回
> db.user3_collection.find({$text:{$search:"a b -c"}}) //查询 包含 a 或 b 但是 不包含 c 的记录
> db.user3_collection.find({$text:{$search:"a b"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) //相似度查询,按相似度asc排序 不使用sort是倒序
6.地理位置索引
经度范围: -180~180
纬度范围: -90~90
a、2D索引:平面地理位置索引,用于查找和存储平面上的点。
位置表示方式:{字段名:[经度,纬度]}
索引创建格式:db.集合.ensureIndex({字段名:"2d"})
查询方式:
(1)、$near查询:查询距离某个点最近的点 db.集合.find({字段名:{$near:[经度,纬度]}})
(2)、$geoWithin查询:查询某个形状内的点
db.集合.find({字段名:{$geoWithin:{$box:[[经度,纬度],[经度,纬度]]}}}) //矩形
db.集合.find({字段名:{$geoWithin:{$center:[[经度,纬度],半径]}}}) //圆形
db.集合.find({字段名:{$geoWithin:{$polygon:[[经度,纬度],[经度,纬度],[经度,纬度]]}}}) //多边形
(3)、geoNear查询:db.runCommand({geoNear:"集合",near:[经度,纬度],maxDistance:最大距离,minDistance:最小距离,num:返回条数})
> db.local.insert({L:[1,1]}) //插入数据 > db.local.insert({L:[1,2]}) > db.local.insert({L:[1,3]}) > db.local.insert({L:[1,4]}) > db.local.insert({L:[1,5]}) > db.local.insert({L:[-180,-90]}) > db.local.insert({L:[-180,90]}) > db.local.insert({L:[180,90]}) > db.local.insert({L:[180,-90]}) > db.local.insert({L:[3,4]}) > db.local.insert({L:[5,7]}) > db.local.ensureIndex({L:"2d"}) //建立索引 { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.local.find({L:{$near:[1,1],$maxDistance:10}}) //2d索引中不支持 $minDistance > db.local.find({L:{$geoWithin:{$box:[[1,2],[3,5]]}}}) //查询一个矩形内的点 > db.local.find({L:{$geoWithin:{$center:[[1,2],1]}}}) //查询一个矩形内的点 > db.local.find({L:{$geoWithin:{$polygon:[[1,2],[3,5],[2,4]]}}}) //查询多边形内的点 } > db.runCommand({geoNear:"local",near:[1,2],maxDistance:10,num:1}) { "results" : [ { "dis" : 0, //查找到的数据距离[1,2]的距离 "obj" : { "_id" : ObjectId("55f8f3bfb2c8d853c09737f0"), "L" : [ 1, 2 ] } } ], "stats" : { "nscanned" : NumberLong(1), //扫描的数据 "objectsLoaded" : NumberLong(1), "avgDistance" : 0, //平均距离 "maxDistance" : 0, //最大距离 "time" : 1 //花费时间 }, "ok" : 1 }
2Dsphere索引:球面地理位置索引,用于查找和存储球面上的点。
索引创建格式:db.集合.ensureIndex({字段名:"2dsphere"})
位置表示方式:GeoJSON 可以表示一个点 一条直线 多边形等
详细了解:http://www.oschina.net/translate/geojson-spec?cmp