MongoDB索引介绍

索引简述

  1. 索引是什么
    索引在数据库技术体系中占据了非常重要的位置,其主要表现为一种目录式的数据结构,用来实现快速的数据查询。通常在实现上,索引是对数据库表(集合)中的某些字段进行抽取、排列之后,形成的一种非常易于遍历读取的数据集合。目前绝大多数的数据库对于索引技术都有非常强大且稳定的支持。
    索引的作用非常类似于一本书的目录。

  2. 索引的分类

    • 按照索引包含的字段数量,可以分为单键索引和组合索引(或复合索引)。
    • 按照索引字段的类型,可以分为主键索引和非主键索引。
    • 按照索引节点与物理记录的对应方式来分,可以分为聚簇索引和非聚簇索引,其中聚簇索引是指索引节点上直接包含了数据记录,而后者则仅仅包含了一个指向数据记录的指针。
    • 按照索引的特性不同,又可以分为唯一索引、稀疏索引、文本索引、地理空间索引等。

单键、复合索引

在MongoDB中,我们可以对集合中的某个字段或某几个字段创建索引,以book实体为例:

{
   
   
        "_id" : ObjectId("67ab68cbf47317cf01307b3b"),
        "title" : "book-0",
        "type" : "technology",
        "favCount" : 93,
        "tags":['popular'],
        "author" : {
   
   
                "name" : "zale"
        }
}
  • 单字段索引
    如果经常使用title这个字段进行搜索,可以为它创建一个单字段的索引

    > db.book.bookCollection.ensureIndex({
          
          title:1})
    {
         
         
            "createdCollectionAutomatically" : true,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }
    

    这里的“title:1”中的1表示所有采用的是升序排列。然而,在单字段的索引中,使用升序和降序并没有什么区别。
    我们也可以对内嵌的文档字段创建索引:db.book.bookCollection.ensureIndex({auth.name:1})

  • 复合索引
    复合索引是多个字段组合而成的索引,其性质和单字段索引类似。但不同的是,复合索引中字段的顺序、字段的升降序对查询性能有直接的影响,因此在设计复合索引时需要考虑不同的查询场景。
    例如,如果需要频繁地查询某分类下地book文档排名,可以按照分类,收藏数量创建一个复合索引,
    db.book.bookCollection.ensureIndex({type:1,favCount:1})

数组索引

数组索引也被称为多值索引,当我们对数组型地字段创建索引时,这个索引就是多值的。多值索引在使用上与普通索引并没有什么不同,只是索引键上会同时产生多个值。

db.book.bookCollection.ensureIndex({
   
   tags:1})

多值索引很容易与复合索引产生混淆,复合索引时多个字段的组合,而多值索引则仅仅是在一个字段上出现了多值。而实际上,多值索引也可以出现在复合索引上,例如:db.book.bookCollection.ensureIndex({type:1,tags:1})。然而,mongodb并不支持一个复合索引中同时出现多个数组字段。

地理空间索引

在移动互联网时代,基于地理位置的检索功能几乎时所有应用系统的标配。
mongodb为地理空间检索提供了非常方便的功能。地理空间索引就是专门用于实现位置检索的一种特殊索引。

db.store.insertOne({
   
   location:{
   
   type:"Point",coordinates:[-122.158574,37.449157]}})   
db.store.ensureIndex({
   
    location: "2dsphere" });
db.store.find({
   
   location:{
   
   $near:{
   
   $geometry:{
   
   type:"Point",coordinates:[-122.158,37.449]},$maxDistance:5000}}})

> {
   
    "_id" : ObjectId("67ab829c2cee149b47c1e30e"), "location" : {
   
    "type" : "Point", "coordinates" : [ -122.158574, 37.449157 ] } }

这里使用$near查询操作符,用于实现附近商家的检索,返回的数据结果会按距离排序

注意:mongodb的地理空间检索基于WGS84坐标系,在与一些地图平台集成时需要注意转换。

唯一性约束

在创建索引时,通过指定unique=true选项可以将其声明为唯一性索引,代码如下:

db.book.ensureIndex({
   
   title:1},{
   
   unique:true})

此后,如果尝试写入2个拥有相同标题的book文档,则会报错;另外,对于指定的字段已经存在重复记录的集合,如果尝试创建唯一性约束的索引,也会提示报错。

  1. 复合索引的唯一性
    除了单字段索引,还可以为复合索引使用唯一约束。例如,如果只是希望分类下的书籍标题保持唯一性,那么可以建立复合式的唯一索引。

    db.book.ensureIndex({
         
         type:1,title:1},{
         
         unique:true})
    
  2. 嵌套文档的唯一性
    唯一性约束同样可以用于嵌套文档的某个字段,这和普通索引没有什么区别,比如:

    db.book.ensureIndex({
         
         author.name:1},{
         
         unique:true})
    

    但如果希望将整个嵌套文档作为唯一性的保证,那么在使用时可能会造成困扰,比如:

    db.book.ensureIndex({
         
         author:1},{
         
         unique:true})
    

    嵌套文档的唯一性约束是严格按照写入顺序进行比较的,如下代码所示,尽管写入的文档内容是一样的,但由于字段的顺序不一致,mongodb仍然认为这是不同的文档。为了避免困扰,尽量少用这种写法。

    db.book.insert({
         
         author:{
         
         age:20,name:"Lwy"}})
    db.book.insert({
         
         author:{
         
         name:"Lwy",age:20}})
    
  3. 数组的唯一性
    如果对数组索引使用唯一性约束,那么可以保证所有的文档之间不会存在重叠的数组元素,代码如下:

    db.book.ensureIndex({
         
         tags:1},{
         
         unique:true})
    db.book.insert({
         
         tags:["t1","t2"]})
    db.book.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值