

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Perencana kueri v2
<a name="query-planner"></a>

Perencana kueri baru untuk Amazon DocumentDB (perencana versi 2.0) memiliki kemampuan pengoptimalan kueri tingkat lanjut dan peningkatan kinerja. Planner versi 2.0 untuk Amazon DocumentDB 5.0 memberikan peningkatan kinerja hingga 10x dibandingkan versi `find` sebelumnya saat menggunakan dan operator dengan indeks. `update` Peningkatan kinerja terutama berasal dari penggunaan rencana indeks yang lebih optimal dan memungkinkan dukungan pemindaian indeks untuk operator seperti operator negasi (`$neq`,`$nin`) dan bersarang. `$elementMatch` Kueri perencana versi 2.0 berjalan lebih cepat melalui teknik estimasi biaya yang lebih baik, algoritme yang dioptimalkan, dan stabilitas yang ditingkatkan. Planner versi 2.0 juga mendukung filter APIs cache paket, yang meningkatkan stabilitas perencana. Dengan fitur ini, Amazon DocumentDB 5.0 sekarang menawarkan kemampuan untuk memilih dari berbagai versi perencana kueri.

**Topics**
+ [Prasyarat](#nqp-prerequisites)
+ [Memilih perencana versi 2.0 sebagai perencana kueri default](#second-concept-chapter)
+ [Praktik terbaik](#nqp-best-practices)
+ [Batasan](#nqp-limitations)
+ [Perbaikan `Find` dan `Update` Operator](#operator-improvements)
+ [Rencanakan API filter cache](#plan-cache-filter-api)
+ [Potensi perbedaan perilaku antara perencana versi 1.0, 2.0, dan MongoDB](#planner-behavior-differences)
+ [Planner versi 2.0 menjembatani kesenjangan perilaku dengan MongoDB](#planner-v2-mongo-gap-bridge)

## Prasyarat
<a name="nqp-prerequisites"></a>

Prasyarat berikut berlaku untuk perencana versi 2.0:
+ Planner versi 2.0 tersedia di semua wilayah di mana engine versi 5.0 tersedia. 
+ Untuk memilih menggunakan versi 2.0 sebagai perencana kueri default, klaster Anda harus menggunakan engine patch versi 3.0.15902 atau yang lebih baru dari Amazon DocumentDB versi 5.0. Untuk langkah-langkah memperbarui ke patch versi mesin terbaru, lihat[Melakukan pembaruan tambalan ke versi mesin cluster](db-cluster-version-upgrade.md).
+ Untuk menetapkan perencana versi 2.0 sebagai perencana kueri default, Anda memerlukan izin IAM untuk memperbarui grup parameter cluster.
+ Untuk Amazon DocumentDB 8.0, perencana versi 3.0 adalah perencana kueri default. Lihat [Perencana kueri v3](query-planner-v3.md) untuk detail.

## Memilih perencana versi 2.0 sebagai perencana kueri default
<a name="second-concept-chapter"></a>

Gunakan langkah-langkah berikut untuk memilih 2.0 sebagai perencana kueri default dari konsol atau CLI:
+ Ikuti langkah-langkah [Memodifikasi parameter cluster Amazon DocumentDB](cluster_parameter_groups-parameters.md) untuk memodifikasi grup parameter cluster Anda.
+ Untuk parameter berjudul 'PlannerVersion', ubah nilainya menjadi 2.0 yang menunjukkan perencana versi 2.0.
+ Pilih **Terapkan segera** (memilih **Terapkan saat reboot** akan membuat pilihan tidak efektif hingga reboot cluster berikutnya).

## Praktik terbaik
<a name="nqp-best-practices"></a>

Untuk hasil yang diharapkan, gunakan praktik terbaik berikut saat menerapkan perencana versi 2.0:
+ Di cluster global, pilih `plannerVersion` nilai yang sama (1.0 atau 2.0) di grup parameter cluster untuk kedua wilayah. Perhatikan bahwa memilih versi perencana yang berbeda di wilayah primer dan sekunder dapat menyebabkan perilaku dan kinerja kueri yang tidak konsisten.
+ Memperbarui ke perencana versi 2.0 selama jendela pemeliharaan terjadwal atau selama periode lalu lintas yang dikurangi akan menjadi yang paling tidak mengganggu, karena mungkin ada peningkatan tingkat kesalahan jika versi perencana diubah saat beban kerja aktif berjalan.
+ Planner versi 2.0 bekerja paling optimal dengan MongoDB shell versi 5.0.

## Batasan
<a name="nqp-limitations"></a>

Batasan berikut berlaku untuk perencana versi 2.0:
+ Planner versi 2.0 tidak didukung dalam cluster elastis, yang akan kembali ke versi perencana 1.0.
+ Perencana versi 2.0 tidak didukung untuk agregasi dan perintah yang berbeda, yang akan kembali ke perencana versi 1.0.
+ Kueri yang berisi regex, pencarian teks, geospasial, jsonschema atau `$expr` dalam filter tidak didukung dengan filter cache paket di perencana versi 2.0.

## Perbaikan `Find` dan `Update` Operator
<a name="operator-improvements"></a>

Planner versi 2.0 mengoptimalkan operasi fundamental termasuk`find`,, `update``delete`, dan `find-and-modify` perintah. Bagian tab berikut menunjukkan kemampuan yang ditingkatkan untuk indeks, serta peningkatan kinerja kueri dengan perencana versi 2.0:

------
#### [ Enhanced index support ]
+ Planner versi 2.0 menambahkan dukungan indeks untuk operator negasi termasuk`$nin`,`$ne`,`$not {eq}`, dan`$not {in}`, serta `$type` dan. `$elemMatch`

  ```
  Sample Document: { "x": 10, "y": [1, 2, 3] }
  
  db.foo.createIndex({ "x": 1, "y": 1 })
  db.foo.find({ "x": {$nin: [20, 30] }})
  db.foo.find({"x":{ $type: "string" }})
  
  db.foo.createIndex({"x.y": 1})
  db.foo.find({"x":{$elemMatch:{"y":{$elemMatch:{"$gt": 3 }}}}})
  ```
+  Perencana versi 2.0 menggunakan indeks jarang atau sebagian bahkan ketika tidak `$exists` ada dalam ekspresi kueri.

  ```
  Sample Document: {"name": "Bob", "email": "example@fake.com" }
  
  Using Planner Version 1.0, you can specify the command as shown below:
  db.foo.find({email: "example@fake.com", email: {$exists: true}})
  
  Using Planner Version 2.0, you can specify command without $exists:
  db.foo.find({ email: "example@fake.com" })
  ```
+ Planner versi 2.0 akan menggunakan indeks sebagian bahkan ketika kondisi kueri tidak sama persis dengan ekspresi filter indeks paral.

  ```
  Sample Document: {"name": "Bob", "age": 34}
  db.foo.createIndex({"age":1},{partialFilterExpression:{"age":{$lt:50}}})
  
  With Planner Version 1.0, index is used only when the query condition meets the partial
   index filter criterion:
       db.foo.find({"age":{$lt:50}})
  
  With Planner Version 2.0, index is used even when the query condition doesn’t meet the index
  criterion:
  db.foo.find({"age":{$lt:30}})
  ```
+ Planner versi 2.0 menggunakan pemindaian indeks sebagian dengan kueri \$1elemMatch.

  ```
  Sample Document: {"name": "Bob", "age": [34,35,36]}
  db.foo.createIndex({"age":1},{partialFilterExpression:{"age":{$lt:50,$gt:20}}})
  db.foo.find({age:{$elemMatch:{$lt:50,$gt:20}}})
  ```
+ Planner versi 2.0 menyertakan dukungan pemindaian indeks untuk`$regex`, tanpa perlu menyediakan `$hint` kode aplikasi Anda. `$regex`mendukung indeks pada pencarian awalan saja.

  ```
  Sample Document: { "x": [1, 2, 3], "y": "apple" }
  db.foo.createIndex({ "x": 1, "y": 1 })
  db.foo.find({"y":{ $regex: "^a" }})
  ```
+ Perencana versi 2.0 meningkatkan kinerja kueri yang melibatkan indeks multi-kunci, dengan kondisi kesetaraan pada bidang multi-kunci.

  ```
  Sample Document: {"x": [1, 2, 3],
  "y": 5}
  db.foo.createIndex({"x": 1, "y":1})
  db.foo.find({"x": 2,
  "y": {$gt: 1}}).limit(1)
  ```
+ Planner versi 2.0 meningkatkan kinerja kueri yang melibatkan beberapa filter, terutama pada koleksi dengan dokumen lebih besar dari 8 KB.

  ```
  Sample Document: {"x": 2,
  "y": 4,
  "z": 9,
  "t": 99}
  db.foo.find({$and: [{"x": {$gt : 1}, "y": {$gt : 3}, "z": {$lt : 10},
  "t":{$lt : 100}}]})
  ```
+ Planner versi 2.0 meningkatkan kinerja kueri saat menggunakan `$in` operator dengan indeks gabungan dengan menghilangkan tahap pengurutan.

  ```
  Sample Document: {"x": 2,
  "y": 4,
  "z": 9,
  "t": 99}
  db.foo.createIndex({"x":1, "y":1})
  db.foo.find({"x":2,
  "y":$in:[1,2,3,4]}).sort({x:1,y:1})
  ```

  Ini juga meningkatkan kinerja kueri yang menggunakan indeks multi-kunci dengan elemen. `$in`

  ```
  Sample Document: {"x": [1, 2, 3]}
  db.foo.createIndex({"x": 1})
  db.foo.find("x":{$in:[>100 elements]})
  ```

------
#### [ Query performance improvements ]
+ Planner versi 2.0 meningkatkan kinerja kueri yang melibatkan beberapa filter, terutama pada koleksi dengan dokumen lebih besar dari 8 KB.

  ```
  Sample Document: {"x": 2,
  "y": 4,
  "z": 9,
  "t": 99}
  db.foo.find({$and: [{"x": {$gt : 1}, "y": {$gt : 3}, "z": {$lt : 10},
  "t":{$lt : 100}}]})
  ```
+ Planner versi 2.0 meningkatkan kinerja kueri saat menggunakan `$in` operator dengan indeks gabungan dengan menghilangkan tahap pengurutan.

  ```
  Sample Document: {"x": 2,
  "y": 4,
  "z": 9,
  "t": 99}
  db.foo.createIndex({"x":1, "y":1})
  db.foo.find({"x":2,
  "y":$in:[1,2,3,4]}).sort({x:1,y:1})
  ```

  Ini juga meningkatkan kinerja kueri yang menggunakan indeks multikey dengan elemen. `$in`

  ```
  Sample Document: {"x": [1, 2, 3]}
  db.foo.createIndex({"x": 1})
  db.foo.find("x":{$in:[>100 elements]})
  ```

------

## Rencanakan API filter cache
<a name="plan-cache-filter-api"></a>

**catatan**  
Indeks teks tidak didukung dengan filter cache paket.
+ Perencana versi 2.0 menambahkan dukungan untuk fitur filter indeks yang memungkinkan Anda menentukan daftar indeks yang dapat digunakan oleh bentuk kueri tertentu. Fitur ini dapat diakses melalui API dan dapat dikontrol dari sisi server. Jika Anda mengalami regresi kueri, fitur ini memberi Anda opsi yang lebih cepat dan lebih fleksibel untuk mengurangi masalah tanpa harus mengubah kode aplikasi Anda.

  ```
  db.runCommand({ planCacheSetFilter: <collection>, query: <query>,
  sort: <sort>, // optional, 
  indexes: [ <index1>, <index2>, ...],
  comment: <any> // optional})
  ```

  Untuk membuat daftar semua filter pada koleksi, gunakan perintah berikut:

  ```
  db.runCommand(
  {
  planCacheListFilters: <collection>
  }
  )
  ```

  Perintah ini menunjukkan semua filter indeks pada koleksi. Contoh output:

  ```
  {
  "filters" : [
  {
  "query" : {a: "@", b: "@"},
  "sort" : {a: 1},
  "indexes" : [
  <index1>,
  ...
  ]
  },
  ...
  ],
  "ok": 1
  }
  ```
+ Anda dapat menggunakan dua bidang baru dari output `explain` perintah untuk menganalisis pemfilteran indeks perencana versi 2.0: `indexFilterSet` dan. `indexFilterApplied` `indexFilterSet`disetel ke “true” jika ada filter indeks yang disetel pada koleksi yang cocok dengan bentuk kueri. `indexFilterApplied`diatur ke “true” jika, dan hanya jika kueri diterapkan indeks filter dan memilih rencana menggunakan indeks dalam daftar filter.

  Anda dapat menghapus filter indeks dengan perintah berikut:

  ```
  db.runCommand(
  {
  planCacheClearFilters: <collection>>
  query: <query pattern>, // optional
  sort: <sort specification>, // optional
  comment: <any>. //optional
  }
  )
  ```

  Untuk menghapus semua filter pada koleksi “foo”, gunakan perintah berikut:

  ```
  db.runCommand({planCacheClearFilters: "foo"})
  ```

  Untuk menghapus bentuk kueri tertentu dengan jenis apa pun, Anda dapat menyalin dan menempelkan bentuk kueri dari output`planCacheListFilters`:

  ```
  db.runCommand({planCacheClearFilters: "foo", query: {a: @}})
  ```

  Untuk menghapus bentuk kueri tertentu dengan bidang tertentu untuk diurutkan berdasarkan, Anda dapat menyalin dan menempelkan bentuk kueri dari output`planCacheListFilters`:

  ```
  db.runCommand({planCacheClearFilters: "foo", query: {a: @},sort: {a: 1}})
  ```

## Potensi perbedaan perilaku antara perencana versi 1.0, 2.0, dan MongoDB
<a name="planner-behavior-differences"></a>

Dalam beberapa kasus tepi, ada kemungkinan bahwa perencana versi 2.0 dapat menghasilkan hasil yang sedikit berbeda dari hasil di MongoDB. Bagian ini membahas beberapa contoh kemungkinan ini.

------
#### [ \$1(update) and \$1(projection) ]
+ Dalam beberapa kasus, `$(update)` dan `$(projection)` operator di MongoDB mungkin berperilaku berbeda dari perencana Amazon DocumentDB versi 1.0. Di bawah ini adalah beberapa contoh:

  ```
  db.students_list.insertMany( [ { _id: 5, student_ids: [ 100, 200 ], grades: [ 95, 100 ], grad_year: [ 2024, 2023 ] } ] )
  ```

  ```
  db.students_list.updateOne({ student_ids: 100, grades: 100, grad_year: 2024 },
  { $set: { “grad_year.$”: 2025 } }
  ```
  + **Perencana versi 1.0** - Bidang Pembaruan 2022
  + **MongoDB** - Bidang Pembaruan 2022
  + **Perencana versi 2.0** - Bidang Pembaruan 2021
+ 

  ```
  db.col.insert({x:[1,2,3]})
  db.col.update({$and:[{x:1},{x:3}]},{$set:{"x.$":500}})
  ```
  + **Perencana versi 1.0** - Secara acak memperbarui elemen pertama cocok
  + **MongoDB** - Secara acak memperbarui elemen pertama yang cocok
  + **Perencana versi 2.0** - Tidak membuat pembaruan
+ 

  ```
  db.col.insert({x:[1,2,3]})
  db.col.find()
  ```
  + **Perencana versi 1.0** - Secara acak memilih elemen yang cocok
  + **MongoDB** - Secara acak memilih elemen yang cocok
  + **Perencana versi 2.0** - Tidak membuat pilihan
+ 

  ```
  db.col.insert({x:100})
  db.col.update({x:100},{x:100})
  ```
  + **Perencana versi 1.0** - nPerubahan hitungan yang dimodifikasi
  + **MongoDB** - NPerubahan hitungan yang dimodifikasi
  + **Perencana versi 2.0** - NModified count tidak berubah ketika diperbarui dengan nilai yang sama.
+ Ketika `$(update)` operator digunakan dengan`$setOnInsert`, perencana versi 1.0 dan MongoDB melempar kesalahan, tetapi perencana versi 2.0 tidak.
+ Mengganti nama bidang yang tidak ada untuk `$field` memunculkan kesalahan di perencana versi 2.0, sedangkan tidak menghasilkan pembaruan di perencana versi 1.0 dan MongoDB.

------
#### [ Index behavior ]
+ Planner versi 2.0 memunculkan kesalahan saat `$hint` diterapkan dengan indeks yang tidak sesuai, sedangkan perencana versi 1.0 dan MongoDB tidak.

  ```
  // Insert
  db.col.insert({x:1})
  db.col.insert({x:2})
  db.col.insert({x:3})
  
  // Create index on x with partialFilter Expression {x:{$gt:2}}
  db.col.createIndex({x:1},{partialFilterExpression:{x:{$gt:2}}})
  
  // Mongodb allows hint on the following queries
  db.col.find({x:1}).hint("x_1")
  // result is no documents returned because {x:1} is not indexed by the partial index
  // Without $hint mongo should return {x:1}, thus the difference in result between COLSCAN and IXSCAN
  
  DocumentDB will error out when $hint is applied on such cases.
  db.col.find({x:1}).hint("x_1")
  Error: error: {
      "ok" : 0,
      "operationTime" : Timestamp(1746473021, 1),
      "code" : 2,
      "errmsg" : "Cannot use Hint for this Query. Index is multi key index , partial index or sparse index and query is not optimized to use this index."
  }
  
  rs0:PRIMARY> db.runCommand({"planCacheSetFilter": "col", "query": { location: {$nearSphere: {$geometry: {type: "Point", coordinates: [1, 1]}}}}, "indexes": ["name_1"]})
  {
      "ok" : 0,
      "operationTime" : Timestamp(1750815778, 1),
      "code" : 303,
      "errmsg" : "Unsupported query shape for index filter $nearSphere"
  }
  ```
+ `$near`tidak dapat digunakan `$hint({“$natural”:1})` dalam perencana versi 2.0.

  ```
  // indexes present are index on x and geo index
  
  rs0:PRIMARY> db.usarestaurants.getIndexes()
  [
      {
          "v" : 4,
          "key" : {
              "_id" : 1
          },
          "name" : "_id_",
          "ns" : "test.usarestaurants"
      },
      {
          "v" : 4,
          "key" : {
              "location" : "2dsphere"
          },
          "name" : "location_2dsphere",
          "ns" : "test.usarestaurants",
          "2dsphereIndexVersion" : 1
      }
  ]
  
  // Planner Version 2.0 will throw an error when $hint is applied with index "x_1"
  rs0:PRIMARY> db.usarestaurants.find({    "location":{       "$nearSphere":{          "$geometry":{             "type":"Point",             "coordinates":[                -122.3516,                47.6156             ]          },          "$minDistance":1,          "$maxDistance":2000       }    } }, {    "name":1 }).hint({"$natural": 1})
  Error: error: {
      "ok" : 0,
      "operationTime" : Timestamp(1746475524, 1),
      "code" : 291,
      "errmsg" : "unable to find index for $geoNear query"
  }
  
  // Planner Version 1.0 and MongoDB will not throw an error
   db.usarestaurants.find({    "location":{       "$nearSphere":{          "$geometry":{             "type":"Point",             "coordinates":[                -122.3516,                47.6156             ]          },          "$minDistance":1,          "$maxDistance":2000       }    } }, {    "name":1 }).hint({"$natural": 1})
  { "_id" : ObjectId("681918e087dadfd99b7f0172"), "name" : "Noodle House" }
  ```
+ Sementara MongoDB mendukung pemindaian indeks regex lengkap, perencana versi 2.0 mendukung pemindaian indeks regex pada bidang awalan saja.

  ```
  // index on x
  db.col.createIndex({x:1})
  
  // index scan is used only for prefix regexes
  rs0:PRIMARY> db.col.find({x: /^x/}).explain()
  {
      "queryPlanner" : {
          "plannerVersion" : 2,
          "namespace" : "test.col",
          "winningPlan" : {
              "stage" : "IXSCAN",
              "indexName" : "x_1",
              "direction" : "forward",
              "indexCond" : {
                  "$and" : [
                      {
                          "x" : {
                              "$regex" : /^x/
                          }
                      }
                  ]
              },
              "filter" : {
                  "x" : {
                      "$regex" : /^x/
                  }
              }
          }
      },
      "indexFilterSet" : false,
      "indexFilterApplied" : false,
      "ok" : 1,
      "operationTime" : Timestamp(1746474527, 1)
  }
  
  // COLSCAN is used for non-prefix regexes
  rs0:PRIMARY> db.col.find({x: /x$/}).explain()
  {
      "queryPlanner" : {
          "plannerVersion" : 2,
          "namespace" : "test.col",
          "winningPlan" : {
              "stage" : "COLLSCAN",
              "filter" : {
                  "x" : {
                      "$regex" : /x$/
                  }
              }
          }
      },
      "indexFilterSet" : false,
      "indexFilterApplied" : false,
      "ok" : 1,
      "operationTime" : Timestamp(1746474575, 1)
  ```
+ Ada beberapa perbedaan yang melekat dalam menggunakan filter cache paket dengan perencana versi 2.0 dibandingkan dengan MongoDB. Sementara perencana versi 2.0 tidak mendukung menentukan “proyeksi” dan “pemeriksaan” dengan filter cache paket, MongoDB melakukannya. Namun, filter indeks MongoDB hanya dalam memori dan hilang setelah restart. Perencana versi 2.0 mempertahankan filter indeks melalui restart dan tambalan.

------
#### [ Others ]
+ Format log audit DHTML saat menggunakan perencana versi 2.0 sedikit berbeda dari versi perencana 1.0.

  ```
  command -  db.col.find({x:1})
  
  ************** Audit logs generated ******************
  
  // v1 format for dml audit logs
  {"atype":"authCheck","ts":1746473479983,"timestamp_utc":"2025-05-05 19:31:19.983","remote_ip":"127.0.0.1:47022","users":[{"user":"serviceadmin","db":"test"}],"param":{"command":"find","ns":"test.col","args":{"batchSize":101,"filter":{"x":1},"find":"col","limit":18446744073709551615,"lsid":{"id":{"$binary":"P6RCGz9ZS4iWBSSHWXW15A==","$type":"4"},"uid":{"$binary":"6Jo8PisnEi3dte03+pJFjdCyn/5cGQL8V2KqaoWsnk8=","$type":"0"}},"maxScan":18446744073709551615,"singleBatch":false,"skip":0,"startTransaction":false},"result":0}}
  
  // v2 formal for dml audit logs
  {"atype":"authCheck","ts":1746473583711,"timestamp_utc":"2025-05-05 19:33:03.711","remote_ip":"127.0.0.1:37754","users":[{"user":"serviceadmin","db":"test"}],"param":{"command":"find","ns":"test.col","args":{"find":"col","filter":{"x":1},"lsid":{"id":{"$binary":"nJ88TGCSSd+BeD2+ZtrhQg==","$type":"4"}},"$db":"test"},"result":0}}
  ```
+ Kondisi indeks sebagai bagian dari rencana penjelasan:

  ```
  rs0:PRIMARY> db.col.createIndex({index1:1})
  {
  	"createdCollectionAutomatically" : false,
  	"numIndexesBefore" : 1,
  	"numIndexesAfter" : 2,
  	"ok" : 1,
  	"operationTime" : Timestamp(1761149251, 1)
  }
  ```

  Perencana versi 2.0 menjelaskan output rencana yang menampilkan kondisi indeks dan filter:

  ```
  rs0:PRIMARY> db.col.find({$and:[{price:{$eq:300}},{item:{$eq:"apples"}}]}).explain()
  {
  	"queryPlanner" : {
  		"plannerVersion" : 2,
  		"namespace" : "test.col",
  		"winningPlan" : {
  			"stage" : "IXSCAN",
  			"indexName" : "price_1",
  			"direction" : "forward",
  			"indexCond" : {
  				"$and" : [
  					{
  						"price" : {
  							"$eq" : 300
  						}
  					}
  				]
  			},
  			"filter" : {
  				"$and" : [
  					{
  						"item" : {
  							"$eq" : "apples"
  						}
  					}
  				]
  			}
  		}
  	},
  	"indexFilterSet" : false,
  	"indexFilterApplied" : false,
  	"ok" : 1,
  	"operationTime" : Timestamp(1761149497, 1)
  }
  ```

  Perencana versi 1.0 menjelaskan keluaran rencana:

  ```
  rs0:PRIMARY> db.col.find({$and:[{price:{$eq:300}},{item:{$eq:"apples"}}]}).explain()
  {
  	"queryPlanner" : {
  		"plannerVersion" : 1,
  		"namespace" : "test.col",
  		"winningPlan" : {
  			"stage" : "IXSCAN",
  			"indexName" : "price_1",
  			"direction" : "forward"
  		}
  	},
  	"ok" : 1,
  	"operationTime" : Timestamp(1761149533, 1)
  }
  ```

------

## Planner versi 2.0 menjembatani kesenjangan perilaku dengan MongoDB
<a name="planner-v2-mongo-gap-bridge"></a>

Ada beberapa area di mana perencana versi 2.0 menutup kesenjangan perilaku dari MongoDB:
+ Planner versi 2.0 memungkinkan pencarian indeks numerik pada array yang diratakan untuk: `$elemMatch`

  ```
  doc: {"x" : [ [ { "y" : 1 } ] ] }
  
  // Planner Version 2 and mongo
  > db.bar.find({"x.0": {$elemMatch: {y: 1}}})
  { "_id" : ObjectId("68192947945e5846634c455a"), "x" : [ [ { "y" : 1 } ] ] }
  > db.bar.find({"x": {$elemMatch: {"0.y": 1}}})
  { "_id" : ObjectId("68192947945e5846634c455a"), "x" : [ [ { "y" : 1 } ] ] }
  
  //Whereas Planner Version 1 wouldn't return any results.
  > db.bar.find({"x.0": {$elemMatch: {y: 1}}})
  > db.bar.find({"x": {$elemMatch: {"0.y": 1}}})
  ```
+ Sementara perencana versi 1.0 mengecualikan string dalam proyeksi, perilaku perencana versi 2.0 sejajar dengan MongoDB dan memperlakukannya sebagai nilai literal”

  ```
  // Planner V2/ MongoDB
  > db.col.find()
  { "_id" : ObjectId("681537738aa101903ed2fe05"), "x" : 1, "y" : 1 }
  > db.col.find({},{x:"string"})
  { "_id" : ObjectId("681537738aa101903ed2fe05"), "x" : "string" }
  
  // Planner V1 treats strings as exclude in projection
  rs0:PRIMARY> db.col.find()
  { "_id" : ObjectId("68153744d42969f11d5cca72"), "x" : 1, "y" : 1 }
  rs0:PRIMARY> db.col.find({},{x:"string"})
  { "_id" : ObjectId("68153744d42969f11d5cca72"), "y" : 1 }
  ```
+ Perencana versi 2.0, seperti MongoDB, tidak mengizinkan proyeksi pada bidang yang sama “x” dan “x.a”:

  ```
  // Planner version 2/MongoDB will error out
  > db.col.find()
  { "_id" : ObjectId("68153da2012265816bc9ba23"), "x" : [ { "a" : 1 }, 3 ] }
   db.col.find({},{"x.a":1,"x":1}) // error
   
  // Planner Version 1 does not error out
  db.col.find()
  { "_id" : ObjectId("68153da2012265816bc9ba23"), "x" : [ { "a" : 1 }, 3 ] }
  
  db.col.find({},{"x.a":1,"x":1})
  { "_id" : ObjectId("68153d60143af947c720d099"), "x" : [ { "a" : 1 }, 3 ] }
  ```
+ Planner versi 2.0, seperti MongoDB, memungkinkan proyeksi pada subdokumen: 

  ```
  // Planner Version2/MongoDB supports projections on subdocuments
   db.col.find()
  { "_id" : ObjectId("681542d8f35ace71f0a50004"), "x" : [ { "y" : 100 } ] }
  > db.col.find({},{"x":{"y":1}})
  { "_id" : ObjectId("681542b7a22d548e4ac9ddea"), "x" : [ { "y" : 100 } ] }
  
  // Planner V1 throws error if projection is subdocument
   db.col.find()
  { "_id" : ObjectId("681542d8f35ace71f0a50004"), "x" : [ { "y" : 100 } ] }
  rs0:PRIMARY> db.col.find({},{"x":{"y":1}})
  Error: error: {
      "ok" : 0,
      "operationTime" : Timestamp(1746223914, 1),
      "code" : 2,
      "errmsg" : "Unknown projection operator y"
  }
  ```
+ Dengan Planner versi 2.0, seperti MongoDB, proyeksi tidak mendukung bidang setelah operator: `$`

  ```
  // Mongo and Planner Version 2 will error out
    db.col.find()
  { "_id" : ObjectId("68155fa812f843439b593f3f"), "x" : [ { "a" : 100 } ] }
   db.col.find({"x.a":100},{"x.$.a":1}) - // error
   
  // v1 will not error out 
   db.col.find()
  { "_id" : ObjectId("68155fa812f843439b593f3f"), "x" : [ { "a" : 100 } ] }
  db.col.find({"x.a":100},{"x.$.a":1})
  { "_id" : ObjectId("68155dee13b051d58239cd0a"), "x" : [ { "a" : 100 } ] }
  ```
+ Planner versi 2.0, seperti MongoDB, memungkinkan penggunaan: `$hint`

  ```
  // v1 will error out on $hint if there are no filters
  db.col.find({}).hint("x_1")
  Error: error: {
      "ok" : 0,
      "operationTime" : Timestamp(1746466616, 1),
      "code" : 2,
      "errmsg" : "Cannot use Hint for this Query. Index is multi key index , partial index or sparse index and query is not optimized to use this index."
  }
  
  
  // Mongo and Planner Version 2 will allow $hint usage
   db.col.find({}).hint("x_1")
  { "_id" : ObjectId("6818f790d5ba9359d68169cf"), "x" : 1 }
  ```