Sejauh ini kita menulis createIndex() dengan field, arah, dan sesekali satu opsi seperti unique. Padahal opsi-opsi itu — index properties — menentukan banyak hal: bagaimana index dinamai, apakah planner boleh memakainya, hingga bagaimana perbandingan string dilakukan. Chapter ini merangkum properti-properti tersebut dalam satu panduan, menguji tiga yang belum pernah kita sentuh (nama kustom, hidden, collation), dan menutup nasib opsi background yang sudah dicabut.

Peta materi Chapter ini:

  • Nama kustom dan fungsinya bagi operasi dropIndex()/collMod.
  • hidden: menyembunyikan index dari planner tanpa menghapusnya.
  • collation: aturan perbandingan string di dalam index.
  • Tabel ringkas seluruh properti beserta statusnya di MongoDB 9.0.

Nama Kustom #

Nama bawaan MongoDB merangkai field dan arah — { penulis: 1, tahun_terbit: -1 } menjadi penulis_1_tahun_terbit_-1. Panjang dan rentan salah tulis; opsi name menggantinya:

js
use latihan_index
db.buku.drop()
db.buku.insertMany([
  { judul: "Laut Bercerita", penulis: "Leila S. Chudori", harga: 98000, tahun_terbit: 2017 },
  { judul: "Bumi", penulis: "Tere Liye", harga: 89000, tahun_terbit: 2014 },
  { judul: "Filosofi Teras", penulis: "Henry Manampiring", harga: 89000, tahun_terbit: 2018 },
  { judul: "Rumah Kaca", penulis: "Tere Liye", harga: 72000, tahun_terbit: 2016 },
  { judul: "Hujan Bulan Juni", penulis: "Sapardi Djoko Damono", harga: 65000, tahun_terbit: 1994 }
])
db.buku.createIndex({ penulis: 1, tahun_terbit: -1 }, { name: "penulis_urut_tahun" })
db.buku.getIndexes()

Output yang Dihasilkan:

text
switched to db latihan_index
true
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('6ad3be4d144c392586345d79'),
    '1': ObjectId('6ad3be4d144c392586345d7a'),
    '2': ObjectId('6ad3be4d144c392586345d7b'),
    '3': ObjectId('6ad3be4d144c392586345d7c'),
    '4': ObjectId('6ad3be4d144c392586345d7d')
  }
}
penulis_urut_tahun
[
  {
    v: 2,
    key: { _id: 1 },
    name: '_id_',
    collation: { locale: 'simple' }
  },
  {
    v: 2,
    key: { penulis: 1, tahun_terbit: -1 },
    name: 'penulis_urut_tahun',
    collation: { locale: 'simple' }
  }
]

Index kini bernama penulis_urut_tahun. Nama adalah alamat utama index: dropIndex("penulis_urut_tahun") menghapusnya, hideIndex() menyasar namanya, dan log aplikasi yang menyalahkan index tertentu menjadi jauh lebih mudah dibaca. Untuk index yang dikelola tim, nama eksplisit semacam ini terbukti lebih awet daripada nama rangkaian yang berubah setiap kali field ditambah.

Menyembunyikan Index dengan hidden #

Ketika sebuah index dicurigai tak terpakai, menghapusnya langsung terasa berisiko — bila ternyata ada query rahasia yang bergantung padanya, performa aplikasi merosot. Properti hidden menyediakan masa percobaan: index tetap ada dan tetap diperbarui saat ada tulisan, tetapi planner tidak boleh memakainya:

js
db.buku.createIndex({ harga: 1 })
function ringkas(kueri) {
  const tahap = kueri.queryPlanner.winningPlan
  return tahap.inputStage ? tahap.inputStage.stage + " lewat " + tahap.inputStage.indexName : tahap.stage
}
print("Normal:      " + ringkas(db.buku.find({ harga: 89000 }).explain()))
db.buku.hideIndex("harga_1")
print("Tersembunyi: " + ringkas(db.buku.find({ harga: 89000 }).explain()))
try {
  db.buku.find({ harga: 89000 }).hint({ harga: 1 }).toArray()
} catch (e) {
  print("Hint:        " + e.message.split(":: caused by ::")[1].trim())
}
db.buku.unhideIndex("harga_1")
print("Kembali:     " + ringkas(db.buku.find({ harga: 89000 }).explain()))

Output yang Dihasilkan:

text
harga_1
[Function: ringkas]
Normal:      IXSCAN lewat harga_1

{
  hidden_old: false,
  hidden_new: true,
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1792261709, i: 14 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1792261709, i: 14 })
}
Tersembunyi: COLLSCAN

Hint:        hint provided does not correspond to an existing index

{
  hidden_old: true,
  hidden_new: false,
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1792261709, i: 15 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1792261709, i: 15 })
}
Kembali:     IXSCAN lewat harga_1

Urutannya jelas: IXSCAN saat normal, COLLSCAN saat tersembunyi, lalu IXSCAN lagi setelah unhideIndex() — respon hideIndex()/unhideIndex() sendiri menampilkan transisi hidden_old → hidden_new. Teks galat pada hint() juga menegaskan statusnya — index tersembunyi diperlakukan seolah tidak ada. mongosh menyediakan hideIndex()/unhideIndex() sebagai pembungkus yang nyaman; di baliknya keduanya menjalankan collMod dengan parameter hidden, dan index _id tidak boleh disembunyikan.

Collation pada Index #

Properti collation mengatur bagaimana string dibandingkan di dalam index. Dengan strength: 2, perbandingan menjadi tidak peka huruf besar/kecil — “bumi” dan “Bumi” dianggap setara:

js
db.buku.createIndex({ judul: 1 }, { collation: { locale: "id", strength: 2 } })
printjson(db.buku.find({ judul: "bumi" }, { _id: 0, judul: 1 }).collation({ locale: "id", strength: 2 }).toArray())
printjson(db.buku.find({ judul: "bumi" }, { _id: 0, judul: 1 }).toArray())

Output yang Dihasilkan:

text
judul_1
[
  {
    judul: 'Bumi'
  }
]

[]

Query pertama membawa collation yang sama dengan index: hasilnya “Bumi” ditemukan. Query kedua tanpa collation memakai perbandingan biner bawaan — “bumi” tidak cocok dengan “Bumi”, dan hasilnya kosong. Aturannya tegas: index ber-collation hanya terpakai oleh query yang menyertakan collation yang sama persis; tanpa itu planner memilih COLLSCAN demi kebenaran hasil.

Tabel Properti dan Nasib background #

PropertiFungsiDibahas di
nameNama kustom indexChapter ini
hiddenMenyembunyikan dari planner (bisa dibalikan)Chapter ini
collationAturan perbandingan stringChapter ini
uniqueMenolak nilai kunci kembarUnique Index
partialFilterExpressionSeleksi document yang masuk indexPartial Index
sparseHanya document yang memiliki fieldSparse Index
expireAfterSecondsPenghapusan otomatis (TTL)TTL Index

Satu nama tidak lagi ada di tabel: opsi background. Sebelum MongoDB 4.2, opsi itu memilih antara pembangunan index yang memblokir atau berjalan di latar. Sejak 4.2 seluruh pembangunan index memakai algoritma hibrida yang optimal, opsi tersebut kehilangan maknanya, dan di 9.0 ia diabaikan sepenuhnya — menyertakannya tidak menghasilkan galat, tetapi juga tidak berpengaruh apa pun. Hilangkan dari ingatan maupun kode lama yang masih ditemui.

Rangkuman #

  • Opsi name memberi index alamat yang stabil dan mudah dibaca — penting untuk dropIndex(), hideIndex(), dan log operasional.
  • hidden (lewat hideIndex()/unhideIndex() atau collMod) mengistirahatkan index dari planner tanpa menghapusnya; hint() pada index tersembunyi ditolak, dan _id tidak bisa disembunyikan.
  • Index ber-collation hanya terpakai query dengan collation yang sama; cocok untuk pencarian tidak pecah huruf besar/kecil.
  • Opsi background sudah tidak berfungsi sejak 4.2 dan diabaikan di 9.0 — jangan menulisnya lagi.