您的位置:首页 > 数据库 > Mongodb

mongodb的索引

2015-09-16 13:58 591 查看
插入准备数据

> 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: