• mongodb 索引实操


    现在我们就开始实操 mongodb 的索引吧

    数据准备

    向 mydoc 集合中,插入多条数据,mydoc 之前是没有存在过的,我们直接使用 db.mydoc.insertMany() ,mongodb 会默认给我们新建这个集合

    db.mydoc.insertMany([
       { item:"canvas", qty:120, size:{ h:28, w:35.5, uom:"cm" }, status:"A", createDate:ISODate("2016-02-06T20:20:13Z") },
       { item:"journal", qty:25, tags:[ {tag:"gray", type:"paper"}, {tag:"red", type:"electron"} ], size:{ h:14, w:21, uom:"cm" }, status:"A", createDate:ISODate("2016-02-07T20:20:13Z") },
       { item:"notebook", qty:50, tags:[ {tag:"yellow", type:"paper"}, {tag:"green", type:"electron"}], size:{ h:8.5, w:11, uom:"in" }, status:"P", createDate:ISODate("2016-02-08T20:20:13Z")},
       { item:"paper", qty:100, tags:[{tag:"yellow", type:"paper"}, {tag:"brown", type:"electron"}], size:{ h:8.5, w:11, uom:"in" }, status:"D", createDate:ISODate("2016-02-09T20:20:13Z") },
       { item:"planner", qty:75, tags:[{tag:"yellow", type:"paper"}, {tag:"green", type:"electron"}], size:{ h:22.85, w:30, uom:"cm" }, status:"D", createDate:ISODate("2016-02-10T20:20:13Z") },
       { item:"postcard", qty:45, tags:[{tag:"black", type:"paper"}, {tag:"green", type:"electron"}], size:{ h:10, w:15.25, uom:"cm" }, status:"P", createDate:ISODate("2016-02-11T20:20:13Z") },
       { item:"sketchbook", qty:80, status:"A", createDate:ISODate("2016-02-12T20:20:13Z") }
    ]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    插入成功

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TDo1XsE1-1666421507047)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e46cc2257add459bae58500e191532d6~tplv-k3u1fbpfcp-zoom-1.image)]

    单字段索引

    使用单字段索引,根据物品名称查询物品

    db.mydoc.createIndex({item:1})
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XnnKzgx4-1666421507049)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c7a9a4340b1d4c679e083597c3ae001c~tplv-k3u1fbpfcp-zoom-1.image)]

    使用 db.mydoc.getIndexes() 查看所有索引,可以查看到刚才我们创建的索引 item_1 , 其中 _id_ 是默认索引

    > db.mydoc.getIndexes()
    [
            {
                    "v" : 2,
                    "key" : {
                            "_id" : 1
                    },
                    "name" : "_id_",
                    "ns" : "mytest.mydoc"
            },
            {
                    "v" : 2,
                    "key" : {
                            "item" : 1
                    },
                    "name" : "item_1",
                    "ns" : "mytest.mydoc"
            }
    ]
    >
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    我们来查询一下数据,看看是否命中索引

    > db.mydoc.find().sort({item:1}).explain()
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ddNWFlcP-1666421507051)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/564ec94025f6481a85c6476d937fb74c~tplv-k3u1fbpfcp-zoom-1.image)]

    通过上图我们可以看到,已经命中索引,并且索引范围是 [MinKey, MaxKey],如果我们查询的时候,sort 里面排序为倒序(-1),那么此处的索引范围就是到过来的 [MaxKey, MinKey] ,感兴趣的 xdm 可以尝试一下

    尝试不加 sort

    如果我们直接 db.mydoc.find().explain() 是不会命中索引的,,mongodb 会默认走 全文索引

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U7ozRDoT-1666421507055)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0a929364ae5043cd8b5bee14c3e328c9~tplv-k3u1fbpfcp-zoom-1.image)]

    复合索引

    索引的顺序跟查询排序相关联

    创建复合索引,status 字段 做升序,qty 字段做降序

    db.mydoc.createIndex({status:1, qty:-1})
    
    • 1

    我们创建的索引一升一降,查询排序的模式必须与索引键的模式匹配或逆向,也就是说,我们查询的时候,

    可以是 {status:-1, qty:1} 也可以是{status:1, qty:-1}

    但是不能 {status:-1, qty:-1} 也不能 {status:1, qty:1}

    因为这样的查询顺序是和我们的索引矛盾的,这两种模式是不能被命中索引的

    TLL 索引

    数据准备

    新建一个 日志集合,插入多条数据,带上最后修改的时间

    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}"}
    ]
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    执行结果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KM4AE83z-1666421507059)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/73813b2160bf43e1b7f218cdbbf8dcbf~tplv-k3u1fbpfcp-zoom-1.image)]

    查询一下 eventlog

    > db.eventlog.find()
    { "_id" : ObjectId("615eb334631f5c41fb6c6c16"), "system" : "trade", "lastModifiedDate" : ISODate("2017-11-12T20:20:13Z"), "context" : "NullPointException, " }
    { "_id" : ObjectId("615eb334631f5c41fb6c6c17"), "system" : "goods", "lastModifiedDate" : ISODate("2017-11-15T20:21:13Z"), "context" : "NullPointException, " }
    { "_id" : ObjectId("615eb334631f5c41fb6c6c18"), "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}" }
    
    • 1
    • 2
    • 3
    • 4

    创建一个 TLL 索引

    创建索引的字段是日期或者是日期数组,不是这种类型的字段,是不会删除文档的

    设置 30秒 后过期,会话、日志,会话过期后会删除集合

    > db.eventlog.createIndex({"lastModifiedDate":1}, {expireAfterSeconds:30})
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iGW3qnzG-1666421507066)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c68f571c96534fbeac884233be44234f~tplv-k3u1fbpfcp-zoom-1.image)]

    30 s 之后,我们再来查询一下数据

    db.eventlog.find()
    
    • 1

    果然是查询不到结果的,文档数据被删除掉了,索引还会在吗?

    > db.eventlog.getIndexes()
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MO87BCRc-1666421507067)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f76c271f701b49889120a2265e6a0312~tplv-k3u1fbpfcp-zoom-1.image)]

    hash 索引

    数据准备

    插入一些数据

    db.mydoc.drop() // 清空表
    
    db.mydoc.insertMany([
       { item:"canvas", qty:120, size:{ h:28, w:35.5, uom:"cm" }, status:"A", createDate:ISODate("2016-02-06T20:20:13Z") },
       { item:"journal", qty:25, tags:[ {tag:"gray", type:"paper"}, {tag:"red", type:"electron"} ], size:{ h:14, w:21, uom:"cm" }, status:"A", createDate:ISODate("2016-02-07T20:20:13Z") },
       { item:"notebook", qty:50, tags:[ {tag:"yellow", type:"paper"}, {tag:"green", type:"electron"}], size:{ h:8.5, w:11, uom:"in" }, status:"P", createDate:ISODate("2016-02-08T20:20:13Z")},
       { item:"paper", qty:100, tags:[{tag:"yellow", type:"paper"}, {tag:"brown", type:"electron"}], size:{ h:8.5, w:11, uom:"in" }, status:"D", createDate:ISODate("2016-02-09T20:20:13Z") },
       { item:"planner", qty:75, tags:[{tag:"yellow", type:"paper"}, {tag:"green", type:"electron"}], size:{ h:22.85, w:30, uom:"cm" }, status:"D", createDate:ISODate("2016-02-10T20:20:13Z") },
       { item:"postcard", qty:45, tags:[{tag:"black", type:"paper"}, {tag:"green", type:"electron"}], size:{ h:10, w:15.25, uom:"cm" }, status:"P", createDate:ISODate("2016-02-11T20:20:13Z") },
       { item:"sketchbook", qty:80, status:"A", createDate:ISODate("2016-02-12T20:20:13Z") }
    ]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    创建 hash 索引

    > db.mydoc.createIndex({item:"hashed"})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查看 hash 索引是否命中

    > db.mydoc.find({item:"paper"}).explain()
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Z4iuWrd-1666421507070)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0921ebfa0e1a485895e4e8f7e7bcee47~tplv-k3u1fbpfcp-zoom-1.image)]

    图中可以看出, IXSCAN 表示为已经命中 hash 索引

    空间索引

    二维索引球体索引 ,官网上可以看这里

    https://docs.mongodb.com/manual/core/2dsphere/

    我们来实践一下 球体索引

    球体空间索引,2dsphere。

    支持类似地球球体上的位置,可以存放 GeoJSON 、传统坐标类型的数据。

    GeoJSON数据

    需要使用嵌入式文档存放,coordinates 指定坐标位置,type 指定坐标类型

    Type 有如下 3 种形式

    • point

    例如可以这样写:location: { type: "Point", coordinates: [-33.856077, 30.848447] }

    • lineString

    例如可以这样写:location: { type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }

    • polygon

    例如可以这样写:`location: { type: “Polygon”,

    coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ]

    }`

    传统坐标数据

    一个字段即可指定坐标位置。

    GeoJSON数据 和 传统坐标数据 两种类型数据,经纬度的存储方式必须是 [经度,纬度] 的数组形式

    开始实践,数据准备

    在 places 集合中插入 2个文档数据

    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"
       }
    ]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建球体空间索引

    db.places.createIndex( { loc:"2dsphere" } )
    
    • 1

    查看索引

    > db.places.getIndexes()
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sgtp7QdE-1666421507071)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2b41229253dc42b28aa338169150f511~tplv-k3u1fbpfcp-zoom-1.image)]

    创建空间索引的复合索引

    以 category 降序,name 升序

    db.places.createIndex( { loc:"2dsphere" , category:-1, name:1 } )
    
    • 1

    查看索引可以看到

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5KaqBOk7-1666421507073)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/66b33f41d870443fb4decfd6b1138628~tplv-k3u1fbpfcp-zoom-1.image)]

    欢迎点赞,关注,收藏

    朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hX6Fkvtc-1666421507074)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32ff4dd3a719414e983b833bed355495~tplv-k3u1fbpfcp-zoom-1.image)]

    好了,本次就到这里

    技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

    我是阿兵云原生,欢迎点赞关注收藏,下次见~

  • 相关阅读:
    Roreg复现
    【数据库编码集】oracle 10g数据库查询中文因编码格式不同,导致显示乱码。客户端转码解决办法,mybatis全局TypeHandler,mp多数据源
    2023年10月小程序云开发cms内容管理无法使用,无法同步内容模型到云开发数据库的解决方案
    大模型算法岗 100 道面试题(含答案)
    多测师肖sir_高级金牌讲师___ui自动化之selenium001
    FITC荧光标记脂多糖 FITC-LPS;CY3、CY5、CY7标记芽霉菌糖/昆布多糖/海洋硫酸多糖/聚二糖/棉籽糖定制合成
    springboot整合kettle和xxljob
    SpringBoot和SpringCloud版本对应
    用moment插件分别取时间戳的年、月、日、时、分、秒
    多级缓存之实现多级缓存
  • 原文地址:https://blog.csdn.net/m0_37322399/article/details/127461911