DAY13 MongoDB 索引(Index) 种类与建立方式

DAY13 MongoDB 索引(Index) 种类与建立方式

什麽是索引(Index)

索引是资料库设计中非常重要的一环,透过针对特定栏位(一个以上)建立索引,使得任何操作能够快速找到资料,这也是为什麽操作的查询条件通常都须建立索引的缘故,所以使用者情境(user scenario)对开发者来说非常重要,如果没有这些情境,开发者无法预测这个功能该如何使用,进而无法设计出合适的结构或者索引等。

预设索引

MongoDB 内的所有 collection 都有一个 Default Index,打开任一文件都会看到一个 _id 栏位,就是这个。

_id 不需要指定,写入资料库时就会自动帮你产生,当然你也可以自己客制化,在某些情境很适合。

索引值排序

MongoDB 索引栏位是有排序的,预设是正序1,反序-1则需要特别设定,至於要使用哪一种排序,需要根据你的使用情境来决定。

通常,跟时间相关都会查询与现在较近的为主,例如最近一个月的营收、这周的进货表等等,这样就很适合使用反序来建立索引。

索引命名

官方的文件载明,建议命名为 [栏位名称1]_[排序]_[栏位名称2]_[排序] 这样的方式。
例如现在有两个栏位分别叫 ProductId 使用正序,CreateTime 使用倒序,那以此建立的 index 会命名为ProductId_1_CreateTime_-1

  • 索引命名长度为 127 bytes

索引种类与建立

单一栏位索引

顾名思义,使用一个栏位建立的 Index。

以下范例皆使用此 employee 的 collection (仅范例使用,没考虑设计上问题)

{
  "_id": ObjectId("60a7755055caee86c7479c96"),
  "name": "Aaron",
  "age": 30,
  "department": 1,
  "startWork": 2021-05-21T00:00:00.000+0800
  "address": {
    "city": "taipei",
    "district": "east"
  },
    "assets": [
    {"sn": "PC001", "name":"personal computer"},
    {"sn": "OD001", "name": "office desk"}
  ]
},
{
  "_id": ObjectId("60a7756955caee86c7479c97"),
  "name": "Brad",
  "age": 32,
  "department": 2,
  "startWork": 2021-04-21T00:00:00.000+0800,
  "address": {
    "city": "hsinchu",
    "district": "south"
  },
    "assets": [
    {"sn": "PC002", "name":"personal computer"},
    {"sn": "OD002", "name": "office desk"}
  ]
}

单一栏位建立索引

针对 department 栏位建立索引:

db.employee.createIndex({"department": 1})

巢状文件栏位索引

Index 也可以建立在 embedded field 上,使用 . 来做阶层索引。以 city 为例:

db.employee.createIndex({"address.city": 1})

复合栏位索引

顾名思义是使用两个以上的栏位组成的索引,在大部分情况都是使用这个的。以上面的范本为例:

db.employee.createIndex({"startWork": -1, "department" : 1})

Multikey栏位索引

Multikey index 是针对栏位是 array 使用的,使用方式如同一般 index 一样,不需要额外指定它是 multikey。

db.employee.createIndex({"assets.sn" : 1})

文字索引

文字索引,建立一个以上栏位的文字查询索引。要特别注意的是一个collection只能有一个文字索引

例如要针对 name 栏位建立文字索引,语法稍微不同,如下:

  • Create
db.employee.createIndex({"name" : "text"})
  • Query

查询时不需指定栏位,需使用 $text $search 语法。

单一字查询:

db.employee.find({$text : {$search: "aaron"}}})

查询多个字直接空白隔开即可,例如我要查询包含 aaron asgard 的名字:

db.employee.find({$text : {$search: "aaron asgard"}}})

查询包含空格的完整字串:

db.employee.find({$text : {$search: \""aaron asgard\""}}})

还有个反向的功能,例如要排除某一个字,可以使用 - 符号:
搜寻 aaron 但不包含 asgard

db.employee.find({$text : {$search: "aaron -asgard"}}})

取得索引

看完後才发现忘记讲如何取得索引,赶紧补上。

db.employee.getIndexes()

删除索引

db.employee.dropIndex({"index_name"})

索引种类大致上介绍到这边,明天继续更深入的内容!


本系列文章会同步发表於我个人的部落格 Pie Note


<<:  【从实作学习ASP.NET Core】Day01 | 前言与建立专案

>>:  Day01 - 前言

Day21 测试写起乃 - Webmock

在写测试的时後,一定会有第三方服务或是会打向外部api的时候,如果不想让他真的去打外部api怕速度过...

Day14 Gin and Go Mod

Background Goland从1.11版本起就开始导入了GO Module功能,这样也不需要再...

[DAY-08] 增进诚实敢言 把一切摊在阳光下

人们如果主动隐瞒某些事 反而会花两倍时间想着那着些事 秘密的问题在於 只要你说出来 他就不再是秘密...

企划实现(14)

GOOGLE登入 第八步:宣告 GoogleSignInClient mgoogleSignInCl...

遇到困难解决困难,没有困难就给自己制造麻烦 -- 论try与expect

异常概述 在程序运行途中,经常会遇到各式各样的错误,这些错误被统称为异常。这类错误大部分都是Synt...