MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Buat Indeks Wildcard di MongoDB

Ada beberapa cara untuk membuat indeks di MongoDB, dan dari MongoDB 4.2, kita bisa membuat indeks wildcard.

Indeks karakter pengganti dapat dianggap sebagai semacam filter yang secara otomatis mencocokkan bidang, sub-dokumen, atau larik apa pun dalam koleksi, lalu mengindeks kecocokan tersebut.

Ini dapat berguna jika dokumen Anda berisi data tidak terstruktur dengan bidang yang berbeda dalam hierarki yang berbeda. Dalam kasus seperti itu, tidak ada cara untuk memprediksi indeks yang seharusnya, karena Anda tidak tahu data apa yang akan ada di setiap dokumen.

Indeks wildcard dapat berguna dengan data tidak terstruktur seperti itu, karena indeks tersebut mengindeks semua nilai skalar bidang, secara otomatis berulang ke subdokumen atau larik apa pun dan mengindeks semua bidang skalar di subdokumen/array.

Contoh Koleksi

Indeks wildcard tidak untuk setiap koleksi. Anda hanya akan membuat indeks karakter pengganti pada koleksi tertentu dengan dokumen yang berisi data tidak terstruktur dengan bidang berbeda dalam hierarki berbeda.

Di bawah ini adalah contoh koleksi yang disebut pets yang mungkin merupakan kandidat yang baik untuk indeks karakter pengganti:

{
	"_id" : 1,
	"name" : "Wag",
	"details" : {
		"type" : "Dog",
		"weight" : 20,
		"awards" : {
			"Florida Dog Awards" : "Top Dog",
			"New York Marathon" : "Fastest Dog",
			"Sumo 2020" : "Biggest Dog"
		}
	}
}
{
	"_id" : 2,
	"name" : "Fetch",
	"details" : {
		"born" : ISODate("2020-06-22T14:00:00Z"),
		"color" : "Black"
	}
}
{
	"_id" : 3,
	"name" : "Scratch",
	"details" : {
		"eats" : [
			"Mouse Porridge",
			"Bird Soup",
			"Caviar"
		],
		"type" : "Cat",
		"born" : ISODate("2020-12-19T14:00:00Z")
	}
}

Masing-masing dari 3 dokumen dalam koleksi ini memiliki details bidang, tetapi mereka berisi bidang yang berbeda dalam bidang itu. Ini tidak konsisten. Ini biasanya akan mempersulit pembuatan indeks, karena kami tidak tahu bidang apa yang akan ada di setiap dokumen. Kami mungkin perlu membuat beberapa indeks, setelah analisis yang cermat terhadap kemungkinan struktur dokumen.

Untungnya kita bisa membuat indeks wildcard.

Tapi pertama-tama, mari kita lihat seperti apa rencana kueri saat menanyakan salah satu bidang tersebut. Bayangkan kita ingin mengetahui anjing mana yang mendapat penghargaan “Anjing Tercepat” di New York Marathon. Kita dapat melakukan hal berikut:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } )

Dan jika kita ingin memeriksa rencana kueri, kita dapat menambahkan explain() sampai akhir:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()

Yang mengembalikan berikut ini:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "PetHotel.pets",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"details.awards.New York Marathon" : {
				"$eq" : "Fastest Dog"
			}
		},
		"queryHash" : "EC0D5185",
		"planCacheKey" : "EC0D5185",
		"winningPlan" : {
			"stage" : "COLLSCAN",
			"filter" : {
				"details.awards.New York Marathon" : {
					"$eq" : "Fastest Dog"
				}
			},
			"direction" : "forward"
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Yang memberi tahu kita bahwa ia akan melakukan pemindaian koleksi (COLLSCAN), yang berarti ia harus memindai setiap dokumen untuk mencari bidang tersebut.

Buat Indeks Wildcard

Berikut ini contoh pembuatan indeks karakter pengganti untuk koleksi di atas.

db.pets.createIndex({ "details.$**": 1 });

Keluaran:

{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}

Itu dia. Indeks wildcard telah dibuat.

Untuk membuat indeks wildcard kami menggunakan nama bidang yang ingin kami buat indeksnya (dalam hal ini details bidang), lalu kami menambahkannya dengan titik (. ), dan kemudian bagian penting, $** bagian.

$** menentukan bahwa indeks karakter pengganti harus dibuat dari bidang ini dan semua subdokumennya.

Awalan $** dengan details membatasi cakupan indeks karakter pengganti hanya pada details lapangan.

Sekarang mari kita periksa kembali rencana kueri untuk kueri yang disebutkan di atas:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()

Hasil:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "PetHotel.pets",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"details.awards.New York Marathon" : {
				"$eq" : "Fastest Dog"
			}
		},
		"queryHash" : "EC0D5185",
		"planCacheKey" : "7DFA23ED",
		"winningPlan" : {
			"stage" : "FETCH",
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"$_path" : 1,
					"details.awards.New York Marathon" : 1
				},
				"indexName" : "details.$**_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"$_path" : [ ],
					"details.awards.New York Marathon" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"$_path" : [
						"[\"details.awards.New York Marathon\", \"details.awards.New York Marathon\"]"
					],
					"details.awards.New York Marathon" : [
						"[\"Fastest Dog\", \"Fastest Dog\"]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Kali ini pemindaian koleksi (COLLSCAN) telah digantikan oleh pemindaian indeks (IXSCAN) pada indeks wildcard kami yang baru dibuat.

Setiap bidang dalam details our kami bidang telah diindeks sebagai jalur/nilai, dan ada entri dalam indeks untuk setiap bidang dalam hierarki. Di mana nilai bidang adalah subdokumen (seperti awards kami bidang), pengindeksan telah turun ke subdokumen dan mengulangi prosesnya.

Membuat Indeks Wildcard di Semua Jalur Bidang

Pada contoh sebelumnya, kami membuat indeks wildcard pada jalur bidang tunggal. Anda dapat membuat indeks karakter pengganti di semua jalur bidang hanya dengan menggunakan $** tanpa mengawalinya dengan bidang.

Misalnya, kita bisa melakukan ini:

db.pets.createIndex({ "$**": 1 });

Itu akan membuat indeks karakter pengganti di semua jalur bidang.

Sebenarnya, itu tidak sepenuhnya benar. Secara default, indeks karakter pengganti tidak dibuat di _id bidang. Untuk memasukkan _id bidang, Anda harus memasukkannya ke dalam wildcardProjection dokumen.

Tidak Dapat Membuat Indeks Wildcard? Periksa Setelan ini.

mongod featureCompatibilityVersion minimal harus 4.2 untuk membuat indeks wildcard.

Anda dapat memeriksa pengaturan ini dengan kode berikut:

db.adminCommand( 
    { 
        getParameter: 1, 
        featureCompatibilityVersion: 1 
    } 
)

Anda dapat mengaturnya menggunakan setFeatureCompatibilityVersion perintah:

db.adminCommand( { setFeatureCompatibilityVersion: "4.4" } )

setFeatureCompatibilityVersion perintah harus dijalankan di admin basis data.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Apakah saya perlu menutup koneksi secara eksplisit?

  2. Bagaimana cara membuat tes junit menggunakan mongoDB yang disematkan dalam aplikasi springboot?

  3. Pencadangan MongoDB Otomatis

  4. Luwak selalu mengembalikan array kosong NodeJS

  5. PyMongo upsert melempar upsert harus menjadi contoh kesalahan bool