254_Mongodb_索引创建

举报
alexsully 发表于 2021/12/17 16:03:53 2021/12/17
【摘要】 索引创建

MongoDB 索引

如果集合中存在许多文档, 通常创建索引 来存储文档中的一个或多个特点字段进行排序存储, 这样查询效率会很高

MongoDB中的索引类型

索引类型

描述

举例

单字段索引

在某一个特定的字段上建立索引 mongoDBID上建立了唯一的单键索引,所以经常会使用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函数来创建索引 在索引字段上进行精确匹配,但不支持范围查询,不支持多键hashHash索引上的入口是均匀分布的,在分片集合中非常有用;

 

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()
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。