254_Mongodb_索引创建
MongoDB 索引
如果集合中存在许多文档, 通常创建索引 来存储文档中的一个或多个特点字段进行排序存储, 这样查询效率会很高
MongoDB中的索引类型
索引类型 |
描述 |
举例 |
单字段索引 |
在某一个特定的字段上建立索引 mongoDB在ID上建立了唯一的单键索引,所以经常会使用id来进行查询; 在索引字段上进行精确匹配、排序以及范围查找都会使用此索引; |
db.users. createIndex({age:- 1}); |
复合索引 |
在多个特定的属性上建立索引 复合索引键的排序顺序,可以确定该索引是否可以支持排序操作; 在索引字段上进行精确匹配、排序以及范围查找都会使用此索引,但与索引的顺序 有关; 为了性能考虑,应删除存在与第一个键相同的单键索引 |
db.users. createIndex({username:1,age: -1,country:1}) |
多键索引 |
在数组的属性上建立索引 针对这个数组的任意值的查询都会定位到这个文档,既多个索引入口或者键值引用 同一个文档 |
db.users. createIndex({favorites.city: 1}) |
空间索引 |
2种平面几何的2d索引,球面几何的2dsphere索引 见后文详解 文本索引 支持在集合中搜索字符串内容 |
db.reviews.createIndex( { co mments: "text" } ) |
Hash索引 |
不同于传统的B-树索引,哈希索引使用hash函数来创建索引 在索引字段上进行精确匹配,但不支持范围查询,不支持多键hash; Hash索引上的入口是均匀分布的,在分片集合中非常有用;
|
db.users. createIndex({username : 'hashed'})
|
1 创建单字段索引
语法
db.collection.createindex(<keys>,<options>)
keys: 设定索引的字段和排序规则, 排序规则 1 表升序, 若-1 表降序
options:
background 创建索引是否在后台进行 默认false
unique 此索引是否为唯一索引, 默认false (唯一索引)
name: 索引名字
partialFilterExpression: 索引值用于筛选条件匹配的文档 (部分索引)
sparse: 索引只用于指定字段的文档 (稀疏索引)
expireAfterSeconds 此参数用于TTL索引中, 可以控制文档报了在集合中的时间
storageEngine: 指定索引的存储引擎
唯一索引
db.collection.createIndex({id:1},{unique:true}) #默认在_id 上创建唯一索引
部分索引
仅索引集合中符合指定过滤器表达式的文档。较低的存储需求,索引创建和维护的成本变小。
db.restaurants.createIndex({ cuisine: 1, name: 1 }, {partialFilterExpression:{ rating:{$gt: 5}}})
稀疏索引
仅索引包含具有索引字段的文档,哪怕索引字段包含空值
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
TLL索引 (time-to-live)
特殊的单字段索引,针对时间类型的字段, 在一定时间后或在特定时间自动从集合中删除文档。对于日志和会话类的信息很有用。
db.eventlog.createIndex( {"lastModifiedDate":1}, {expireAfterSeconds:3600 })
db.eventlog.createIndex( {"lastModifiedDate":1}, {expireAfterSeconds: 60*60*24*7 }) #单位秒 s
特点
TTL索引不可以是复合索引
如果索引字段不是时间类型, 文档不会删除
TTL 每60s运行一次,移除过期文档
如果时间类型字段已经被定义为其它索引, 则无法通过TTL 索引来删除此文档
db.eventlog.drop();
db.eventlog.insert([
{system:"trade", lastModifiedDate:ISODate("2017-11-12T20:20:13Z"), context:"NullPointException, "},
{system:"goods", lastModifiedDate:ISODate("2017-11-15T20:21:13Z"), context:"NullPointException, "},
{system:"mongodb", lastModifiedDate:ISODate("2017-11-16T20:22:13Z"), context:"2019-11-12 18:18:52.426 [main] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:2, serverValue:2409}"}
]);
// TLL 索引,创建索引的字段是日期或者是日期数组。不是这种类型的字段,是不会删除文档的,
// 30秒后过期,会话、日志
db.eventlog.createIndex({"lastModifiedDate":1}, {expireAfterSeconds:30});
db.eventlog.find();
不区分大小写 #strength
db.fruit.createIndex({ type: 1},{collation:{ locale:'en', strength:2 } } )
全文本索引
用于查询MongoDB中的文本文档,可以包含一个或多个字段; 建立索引时需要将字段指定为 文本索引 “text”, 查询搭配 $text操作符
特点
一个集合最多只能创建一个全文本索引,写入速度会变慢
全文本索引可选择所有字符串类型的字段, 可用全字段或者指定字段创建 可设置权重
全文本索引暂不支持中文索引
例
#部分字段
db.product.createindex({“productName”:”text”, “productStatus”: “text”})
#将product 集合中所有字符串的字段创建成全文本索引, 用”$**”代表文档中所有字符串类型
db.product.createindex( {“$**” : “text”} )
# 创建文本索引搭配权重值
db.product.createindex( {“$**” : “text”} , {“weights”: {“ProductName” :10, “ProductMode”:5 } } )
# 使用$text 操作符 查询含有 rose文档
db.product.find({$text:{$search: “rose”}}).pretty()
地理空间索引
两类地理空间索引: 1) 2dsphere 2) 2d
2dsphere 支持查询球体上位置,支持 GeoJSON 和传统坐标类型的数据
GeoJSON数据 需要使用签入文档, 通过coordinate字段来指定坐标位置, 通过type来指定坐标类型, type分为如下三类
1 点 point 若type为point, coordinates 字段只有一个坐标
2 线 lineString , 若type为lineString, coordinates 字段有两个坐标
3 多边形 Polygon, 若type为Polygon 则coordinates 会有两个以上坐标
// 球体空间
db.places.drop();
db.places.insert([
{
loc:{ type:"Point", coordinates:[ -73.97, 40.77 ] },
name:"Central Park", category:"Parks"
},
{
loc:{ type:"Point", coordinates:[ -73.88, 40.78 ] },
name:"La Guardia Airport", category:"Airport"
}
]);
// 创建球体空间索引
db.places.createIndex( { loc:"2dsphere" } )
// 创建空间索引的复合索引
db.places.createIndex( { loc:"2dsphere" , category:-1, name:1 } )
// 聚合使用,距指定点最近到最远的顺序输出文档
db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated", # 该参数用于计算只读坐标文档与文档中坐标之间的距离
key: “loc” # 指定 loc 字段上的2dsphere 索引
minDistance: 2,
query: { category: "Parks" },
includeLocs: "dist.location",
spherical: true
}
}
])
传统坐标数据: 只需要一个字段来指定坐标位置
2d 此索引类型支持查询二维平面位置,仅支持传统坐标类型的数据
db.location.insert([
{ _id:100, pos:{lng:126.9, lat:35.2}, co:[126.9, 35.2], type:"restaurant"},
{ _id:200, pos:{lng:127.5, lat:36.1}, co:[127.5, 36.1], type:"restaurant"},
{ _id:300, pos:{lng:128.0, lat:36.7}, co:[128.0, 36.7], type:"national park"}
])
// 创建2d索引
db.location.createIndex({co:"2d"})
db.places.aggregate([
{
$geoNear: {
near:[126,30]
distanceField: "dist.location",
key: “co” # 指定 co 字段上的2d索引
}
}
])
// 查询离目标点(-70,30)距离最近的10个点
db.location.find({"co":{$near:[-70,30]}}).limit(10);
// $within 参数可以代替$near来查找一个形状之内结果,
// 必须指定该矩形的左下角和右上角坐标
// 还可以支持$box(矩形)和$center(圆环)的范围查询
var box = [[10,10], [140,40]];
db.location.find({"co":{$within:{"$box":box}}})
// 创建geoHaystack索引
db.location.createIndex({pos:"geoHaystack", type:1} , {bucketSize:1})
// 查询需要使用geoSearch关键字指定集合,查询附近10米范围的餐馆
// Haystack索引不适合查询最接近特定位置的文档的完整列表。与存储桶大小相比,最接近的文档可能会更远。
// find方法无法使用geoHaystack索引,需要使用db.rumCommand方法
db.runCommand( {geoSearch:"location", search:{ type:"restaurant" } ,
near:[127, 36.8], maxDistance:1} )
// 首选通过find方法查询,也可以通过db.runCommand方式查询。
// 这种方式返回的结果中,包含距离目标点的距离和一些利于排除故障的信息
db.runCommand({
geoSearch:"location", near:[126,30],
maxDistance:16, search:{type:"restaurant"},
imit:10
});
2 重建索引
索引出现损坏,可以用reindex()方法重建索引, 本质是将索引删除后重建, 对于副本集来说,索引重建只会在当前mongod进行,不会同步给其它节点
不推荐使用
db.collection.reindex()
3 查询索引 getindexes() & totalindexsize()
查看索引
db.collection.getindexes()
查看集合中所有索引的大小
db.collection.totalindexSize()
4 删除索引 dropindex()
# db.collection.dropindex<index_name> 删除指定索引名的索引
db.product.dropindex(“Weight_1”)
# dropindex() 删除除 “_id” 字段外的其它索引, 会锁库
db.collection.dropindexes() db.product.dropindexes()
- 点赞
- 收藏
- 关注作者
评论(0)