Mongodb menemukan _id lebih besar dari

Metode

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2 digunakan untuk melakukan kueri di MongoDB. Permintaan mengembalikan subkumpulan dokumen dalam koleksi, dari tidak ada dokumen sama sekali hingga seluruh koleksi. Dokumen mana yang dikembalikan ditentukan oleh argumen pertama ke
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2, yang merupakan dokumen yang menentukan kriteria kueri

Dokumen kueri kosong (mis. e. ,

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
_4) cocok dengan semua yang ada di koleksi. Jika
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
_2 tidak diberikan dokumen kueri, defaultnya adalah
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
4. Misalnya berikut ini

> db.c.find()

mencocokkan setiap dokumen dalam koleksi c (dan mengembalikan dokumen-dokumen ini secara berkelompok)

Saat kami mulai menambahkan pasangan kunci/nilai ke dokumen kueri, kami mulai membatasi pencarian kami. Ini bekerja dengan cara yang mudah untuk sebagian besar jenis. angka cocok dengan angka, boolean cocok dengan boolean, dan string cocok dengan string. Meminta tipe sederhana semudah menentukan nilai yang Anda cari. Misalnya, untuk menemukan semua dokumen dengan nilai

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
7 adalah 27, kita dapat menambahkan pasangan kunci/nilai tersebut ke dokumen kueri

> db.users.find({"age" : 27})

Jika kami memiliki string yang ingin kami cocokkan, seperti kunci

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
8 dengan nilai
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
9, kami menggunakan pasangan kunci/nilai itu sebagai gantinya

> db.users.find({"username" : "joe"})

Beberapa ketentuan dapat dirangkai bersama dengan menambahkan lebih banyak pasangan kunci/nilai ke dokumen kueri, yang ditafsirkan sebagai “

> db.users.find({"age" : 27})
00 DAN
> db.users.find({"age" : 27})
01 DAN … DAN
> db.users.find({"age" : 27})
02. Misalnya, untuk mendapatkan semua pengguna yang berusia 27 tahun dengan nama pengguna "joe", kita dapat meminta yang berikut ini

> db.users.find({"username" : "joe", "age" : 27})

Menentukan Kunci Yang Akan Dikembalikan

Terkadang Anda tidak perlu mengembalikan semua pasangan kunci/nilai dalam dokumen. Jika demikian, Anda dapat meneruskan argumen kedua ke

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2 (atau
> db.users.find({"age" : 27})
04) dengan menentukan kunci yang Anda inginkan. Ini mengurangi jumlah data yang dikirim melalui kabel dan waktu serta memori yang digunakan untuk memecahkan kode dokumen di sisi klien

Misalnya, jika Anda memiliki koleksi pengguna dan Anda hanya tertarik pada kunci

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
8 dan
> db.users.find({"age" : 27})
06, Anda dapat mengembalikan kunci tersebut dengan kueri berikut

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}

Seperti yang Anda lihat dari keluaran sebelumnya, kunci

> db.users.find({"age" : 27})
07 dikembalikan secara default, meskipun tidak diminta secara khusus

Anda juga dapat menggunakan parameter kedua ini untuk mengecualikan pasangan kunci/nilai tertentu dari hasil kueri. Misalnya, Anda mungkin memiliki dokumen dengan berbagai kunci, dan satu-satunya hal yang Anda tahu adalah bahwa Anda tidak pernah ingin mengembalikan kunci

> db.users.find({"age" : 27})
08

> db.users.find({}, {"fatal_weakness" : 0})

Ini juga dapat mencegah

> db.users.find({"age" : 27})
07 dikembalikan

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}

Ada beberapa batasan pada kueri. Nilai dokumen kueri harus konstan sejauh menyangkut basis data. (Ini bisa menjadi variabel normal dalam kode Anda sendiri. ) Artinya, tidak bisa merujuk ke nilai kunci lain dalam dokumen. Misalnya, jika kami menyimpan inventaris dan memiliki kunci

> db.users.find({"age" : 27})
10 dan
> db.users.find({"age" : 27})
11, kami tidak dapat membandingkan nilainya dengan mengajukan kueri berikut

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work

Ada beberapa cara untuk melakukan ini (lihat ), tetapi Anda biasanya akan mendapatkan kinerja yang lebih baik dengan sedikit merestrukturisasi dokumen Anda, sehingga kueri "normal" sudah cukup. Dalam contoh ini, kita dapat menggunakan kunci

> db.users.find({"age" : 27})
12 dan
> db.users.find({"age" : 27})
10. Kemudian, setiap kali seseorang membeli item, kami mengurangi nilai kunci
> db.users.find({"age" : 27})
10 satu per satu. Terakhir, kita dapat melakukan kueri sederhana untuk memeriksa item mana yang kehabisan stok

> db.stock.find({"in_stock" : 0})

Kueri dapat melampaui pencocokan tepat yang dijelaskan di bagian sebelumnya;

> db.users.find({"age" : 27})
15,
> db.users.find({"age" : 27})
16,
> db.users.find({"age" : 27})
17, and
> db.users.find({"age" : 27})
18 are all comparison operators, corresponding to <, <=, >, and >=, respectively. They can be combined to look for a range of values. For example, to look for users who are between the ages of 18 and 30, we can do this:

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})

Ini akan menemukan semua dokumen di mana bidang "

> db.users.find({"age" : 27})
_19" lebih besar dari atau sama dengan 18 DAN kurang dari atau sama dengan 30

Jenis kueri rentang ini sering berguna untuk tanggal. Misalnya untuk mencari orang yang mendaftar sebelum 1 Januari 2007, kita bisa melakukannya

> db.users.find({"age" : 27})
0

Pencocokan tepat pada tanggal kurang berguna, karena tanggal hanya disimpan dengan presisi milidetik. Seringkali Anda menginginkan sepanjang hari, minggu, atau bulan, membuat kueri rentang diperlukan

Untuk menanyakan dokumen yang nilai kuncinya tidak sama dengan nilai tertentu, Anda harus menggunakan operator bersyarat lainnya,

> db.users.find({"age" : 27})
20, yang merupakan singkatan dari “not equal. ” Jika Anda ingin menemukan semua pengguna yang tidak memiliki nama pengguna "joe", Anda dapat menanyakannya menggunakan ini

> db.users.find({"age" : 27})
1

> db.users.find({"age" : 27})
20 dapat digunakan dengan tipe apapun

Ada dua cara untuk melakukan kueri ATAU di MongoDB.

> db.users.find({"age" : 27})
22 dapat digunakan untuk meminta berbagai nilai untuk satu kunci.
> db.users.find({"age" : 27})
23 lebih umum;

Jika Anda memiliki lebih dari satu kemungkinan nilai yang cocok untuk satu kunci, gunakan larik kriteria dengan

> db.users.find({"age" : 27})
22. Misalnya, kita mengadakan undian dan nomor tiket yang menang adalah 725, 542, dan 390. Untuk menemukan ketiga dokumen ini, kita dapat membuat kueri berikut

> db.users.find({"age" : 27})
2

> db.users.find({"age" : 27})
22 sangat fleksibel dan memungkinkan Anda untuk menentukan kriteria dari berbagai jenis serta nilai. Misalnya, jika kami secara bertahap memigrasikan skema kami untuk menggunakan nama pengguna alih-alih nomor ID pengguna, kami dapat menanyakan keduanya dengan menggunakan ini

> db.users.find({"age" : 27})
3

Ini mencocokkan dokumen dengan

> db.users.find({"age" : 27})
_26 sama dengan 12345, dan dokumen dengan
> db.users.find({"age" : 27})
26 sama dengan
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
9

Jika

> db.users.find({"age" : 27})
_22 diberikan sebuah array dengan satu nilai, itu berperilaku sama seperti pencocokan langsung nilai. Misalnya,
> db.users.find({"age" : 27})
_30 cocok dengan dokumen yang sama dengan
> db.users.find({"age" : 27})
31

Kebalikan dari

> db.users.find({"age" : 27})
_22 adalah
> db.users.find({"age" : 27})
33, yang mengembalikan dokumen yang tidak cocok dengan salah satu kriteria dalam larik. Jika kami ingin mengembalikan semua orang yang tidak memenangkan apa pun dalam undian, kami dapat menanyakannya dengan ini

> db.users.find({"age" : 27})
4

Kueri ini mengembalikan semua orang yang tidak memiliki tiket dengan nomor tersebut

> db.users.find({"age" : 27})
22 memberi Anda permintaan ATAU untuk satu kunci, tetapi bagaimana jika kami perlu menemukan dokumen di mana
> db.users.find({"age" : 27})
35 adalah 725 atau
> db.users.find({"age" : 27})
36 adalah
> db.users.find({"age" : 27})
37? .
> db.users.find({"age" : 27})
23 mengambil berbagai kriteria yang memungkinkan. Dalam kasus undian, menggunakan
> db.users.find({"age" : 27})
23 akan terlihat seperti ini

> db.users.find({"age" : 27})
5

> db.users.find({"age" : 27})
23 dapat berisi persyaratan lainnya. Jika, misalnya, kami ingin mencocokkan salah satu dari tiga nilai
> db.users.find({"age" : 27})
35 atau kunci
> db.users.find({"age" : 27})
36, kami dapat menggunakan ini

> db.users.find({"age" : 27})
6

Dengan kueri tipe AND normal, Anda ingin mempersempit hasil Anda sejauh mungkin dalam argumen sesedikit mungkin. Kueri tipe OR adalah kebalikannya. mereka paling efisien jika argumen pertama cocok dengan dokumen sebanyak mungkin

Meskipun

> db.users.find({"age" : 27})
_23 akan selalu berfungsi, gunakan
> db.users.find({"age" : 27})
22 bila memungkinkan karena pengoptimal kueri menanganinya dengan lebih efisien

> db.users.find({"age" : 27})
46 adalah metakondisional. itu dapat diterapkan di atas kriteria lainnya. Sebagai contoh, mari pertimbangkan operator modulus,
> db.users.find({"age" : 27})
47.
> db.users.find({"age" : 27})
47 kueri untuk kunci yang nilainya, jika dibagi dengan nilai pertama yang diberikan, memiliki sisa nilai kedua

> db.users.find({"age" : 27})
7

Permintaan sebelumnya mengembalikan pengguna dengan

> db.users.find({"age" : 27})
_49 dari 1, 6, 11, 16, dan seterusnya. Sebaliknya, jika kita ingin mengembalikan pengguna dengan
> db.users.find({"age" : 27})
_49 dari 2, 3, 4, 5, 7, 8, 9, 10, 12, dll. , kita dapat menggunakan
> db.users.find({"age" : 27})
_46

> db.users.find({"age" : 27})
_8

> db.users.find({"age" : 27})
46 dapat sangat berguna dalam hubungannya dengan ekspresi reguler untuk menemukan semua dokumen yang tidak cocok dengan pola tertentu (penggunaan ekspresi reguler dijelaskan di bagian ini)

Jika Anda melihat pengubah pembaruan di bab sebelumnya dan dokumen kueri sebelumnya, Anda akan melihat bahwa kunci dengan awalan $ berada di posisi yang berbeda. Dalam kueri,

> db.users.find({"age" : 27})
_15 ada di dokumen dalam; . Ini umumnya berlaku. kondisional adalah kunci dokumen dalam, dan pengubah selalu merupakan kunci dalam dokumen luar

Beberapa kondisi dapat diletakkan pada satu kunci. Misalnya, untuk menemukan semua pengguna berusia antara 20 dan 30 tahun, kami dapat meminta

> db.users.find({"age" : 27})
17 dan
> db.users.find({"age" : 27})
15 pada kunci
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
7

> db.users.find({"age" : 27})
_9

Sejumlah persyaratan dapat digunakan dengan satu kunci. Namun, beberapa pengubah pembaruan tidak dapat digunakan pada satu kunci. Misalnya, Anda tidak dapat memiliki dokumen pengubah seperti

> db.users.find({"age" : 27})
58 karena dokumen tersebut mengubah
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
7 dua kali. Dengan persyaratan kueri, aturan seperti itu tidak berlaku

Ada beberapa "meta-operator" yang masuk ke dokumen luar. "

> db.users.find({"age" : 27})
_60“, "
> db.users.find({"age" : 27})
61“, dan "
> db.users.find({"age" : 27})
62“. Mereka semua memiliki bentuk yang serupa

> db.users.find({"username" : "joe"})
_0

Kueri ini akan mencocokkan dokumen dengan kolom "

> db.users.find({"age" : 27})
63" keduanya kurang dari 1 dan sama dengan 4. Meskipun ini tampak seperti kondisi yang kontradiktif, hal ini dapat dipenuhi jika kolom "
> db.users.find({"age" : 27})
63" adalah sebuah array.
> db.users.find({"age" : 27})
65 akan cocok. Perhatikan bahwa pengoptimal kueri tidak mengoptimalkan "
> db.users.find({"age" : 27})
60" serta operator lainnya. Kueri ini akan lebih efisien untuk disusun sebagai

> db.users.find({"username" : "joe"})
_1

Seperti yang dibahas di Bab 2, MongoDB memiliki berbagai jenis yang dapat digunakan dalam dokumen. Beberapa jenis ini memiliki perilaku khusus saat melakukan kueri

> db.users.find({"age" : 27})
67 berperilaku agak aneh. Itu memang cocok dengan dirinya sendiri, jadi jika kita memiliki koleksi dengan dokumen-dokumen berikut

> db.users.find({"username" : "joe"})
_2

kita dapat meminta dokumen yang

> db.users.find({"age" : 27})
_68 kuncinya adalah
> db.users.find({"age" : 27})
67 dengan cara yang diharapkan

> db.users.find({"username" : "joe"})
_3

Namun,

> db.users.find({"age" : 27})
_67 tidak hanya cocok dengan dirinya sendiri tetapi juga cocok “tidak ada. ” Jadi, meminta kunci dengan nilai
> db.users.find({"age" : 27})
67 akan mengembalikan semua dokumen yang tidak memiliki kunci itu

> db.users.find({"username" : "joe"})
_4

Jika kita hanya ingin menemukan kunci yang nilainya

> db.users.find({"age" : 27})
67, kita dapat memeriksa bahwa kuncinya adalah
> db.users.find({"age" : 27})
67 dan ada menggunakan kondisional
> db.users.find({"age" : 27})
74

> db.users.find({"username" : "joe"})
_5

Sayangnya, tidak ada

> db.users.find({"age" : 27})
75 operator, yang membuat ini sedikit canggung, tetapi
> db.users.find({"age" : 27})
22 dengan satu elemen setara

Ekspresi reguler berguna untuk pencocokan string yang fleksibel. Misalnya, jika kita ingin mencari semua pengguna dengan nama Joe atau joe, kita dapat menggunakan ekspresi reguler untuk melakukan pencocokan case-insensitive

> db.users.find({"username" : "joe"})
_6

Bendera ekspresi reguler (misalnya,

> db.users.find({"age" : 27})
77) diperbolehkan tetapi tidak wajib. Jika kita ingin mencocokkan tidak hanya berbagai kapitalisasi joe, tetapi juga joey, kita dapat terus menyempurnakan ekspresi reguler kita

> db.users.find({"username" : "joe"})
_7

MongoDB menggunakan pustaka Perl Compatible Regular Expression (PCRE) untuk mencocokkan ekspresi reguler; . Sebaiknya periksa sintaks Anda dengan shell JavaScript sebelum menggunakannya dalam kueri untuk memastikannya cocok dengan apa yang menurut Anda cocok.

Catatan

MongoDB dapat memanfaatkan indeks untuk kueri pada ekspresi reguler awalan (mis. g. ,

> db.users.find({"age" : 27})
_78). Indeks tidak dapat digunakan untuk pencarian yang tidak peka huruf besar/kecil (
> db.users.find({"age" : 27})
79)

Ekspresi reguler juga bisa cocok dengan dirinya sendiri. Sangat sedikit orang yang memasukkan ekspresi reguler ke dalam database, tetapi jika Anda memasukkannya, Anda dapat mencocokkannya dengan dirinya sendiri

> db.users.find({"username" : "joe"})
_8

Permintaan untuk elemen array dirancang untuk berperilaku seperti cara permintaan skalar. Misalnya, jika array adalah daftar buah, seperti ini

> db.users.find({"username" : "joe"})
_9

kueri berikut

> db.users.find({"username" : "joe", "age" : 27})
_0

akan berhasil mencocokkan dokumen. Kita dapat menanyakannya dengan cara yang sama seperti jika kita memiliki dokumen yang tampak seperti dokumen (ilegal).

> db.users.find({"age" : 27})
80

Jika Anda perlu mencocokkan array dengan lebih dari satu elemen, Anda dapat menggunakan

> db.users.find({"age" : 27})
81. Ini memungkinkan Anda untuk mencocokkan daftar elemen. Misalnya, kita membuat koleksi dengan tiga elemen

> db.users.find({"username" : "joe", "age" : 27})
_1

Kemudian kita dapat menemukan semua dokumen dengan elemen

> db.users.find({"age" : 27})
_82 dan
> db.users.find({"age" : 27})
83 dengan menanyakan menggunakan
> db.users.find({"age" : 27})
81

> db.users.find({"username" : "joe", "age" : 27})
_2

Urutan tidak masalah. Pemberitahuan

> db.users.find({"age" : 27})
_83 datang sebelum
> db.users.find({"age" : 27})
82 di hasil kedua. Menggunakan larik satu elemen dengan
> db.users.find({"age" : 27})
81 sama dengan tidak menggunakan
> db.users.find({"age" : 27})
81. Misalnya,
> db.users.find({"age" : 27})
_89 akan cocok dengan dokumen yang sama dengan
> db.users.find({"age" : 27})
90

Anda juga dapat membuat kueri dengan pencocokan persis menggunakan seluruh larik. Namun, pencocokan tepat tidak akan cocok dengan dokumen jika ada elemen yang hilang atau berlebihan. Misalnya, ini akan cocok dengan dokumen pertama di atas

> db.users.find({"username" : "joe", "age" : 27})
_3

Tapi ini tidak akan

> db.users.find({"username" : "joe", "age" : 27})
_4

dan ini juga tidak

> db.users.find({"username" : "joe", "age" : 27})
_5

Jika Anda ingin meminta elemen tertentu dari array, Anda dapat menentukan indeks menggunakan sintaks

> db.users.find({"age" : 27})
91.
> db.users.find({"age" : 27})
_92

> db.users.find({"username" : "joe", "age" : 27})
_6

Array selalu diindeks 0, jadi ini akan mencocokkan elemen array ketiga dengan string

> db.users.find({"age" : 27})
93

Persyaratan yang berguna untuk kueri array adalah

> db.users.find({"age" : 27})
94, yang memungkinkan Anda untuk meminta array dengan ukuran tertentu. Ini sebuah contoh

> db.users.find({"username" : "joe", "age" : 27})
_7

Satu permintaan umum adalah untuk mendapatkan rentang ukuran.

> db.users.find({"age" : 27})
94 tidak dapat digabungkan dengan $ kondisional lainnya (dalam contoh ini,
> db.users.find({"age" : 27})
17), tetapi kueri ini dapat diselesaikan dengan menambahkan kunci
> db.users.find({"age" : 27})
97 ke dokumen. Kemudian, setiap kali Anda menambahkan elemen ke array, tambahkan nilai
> db.users.find({"age" : 27})
97. Jika pembaruan asli terlihat seperti ini

> db.users.find({"username" : "joe", "age" : 27})
_8

itu hanya dapat diubah menjadi ini

> db.users.find({"username" : "joe", "age" : 27})
_9

Penambahan sangat cepat, jadi penalti kinerja apa pun dapat diabaikan. Menyimpan dokumen seperti ini memungkinkan Anda melakukan kueri seperti ini

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_0

Sayangnya, teknik ini tidak bekerja dengan baik dengan operator

> db.users.find({"age" : 27})
99

Seperti disebutkan sebelumnya dalam bab ini, argumen kedua opsional untuk

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2 menentukan kunci yang akan dikembalikan. Operator
> db.users.find({"username" : "joe"})
_01 khusus dapat digunakan untuk mengembalikan subset elemen untuk kunci array

Misalnya, kita memiliki dokumen postingan blog dan ingin mengembalikan 10 komentar pertama

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_1

Sebagai alternatif, jika kita menginginkan 10 komentar terakhir, kita dapat menggunakan −10

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_2

> db.users.find({"username" : "joe"})
_01 juga dapat mengembalikan halaman di tengah hasil dengan mengambil offset dan jumlah elemen yang akan dikembalikan

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_3

Ini akan melewati 23 elemen pertama dan mengembalikan elemen ke-24 hingga ke-33. Jika ada kurang dari 33 elemen dalam array, itu akan mengembalikan sebanyak mungkin

Kecuali ditentukan lain, semua kunci dalam dokumen dikembalikan saat

> db.users.find({"username" : "joe"})
01 digunakan. Ini tidak seperti penentu kunci lainnya, yang menekan kunci yang tidak disebutkan agar tidak dikembalikan. Misalnya, jika kita memiliki dokumen posting blog yang terlihat seperti ini

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_4

dan kami melakukan

> db.users.find({"username" : "joe"})
_01 untuk mendapatkan komentar terakhir, kami akan mendapatkan ini

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_5

Baik

> db.users.find({"username" : "joe"})
_05 dan
> db.users.find({"username" : "joe"})
06 masih dikembalikan, meskipun tidak secara eksplisit disertakan dalam penentu kunci

Mengembalikan elemen array yang cocok

"

> db.users.find({"username" : "joe"})
07" berguna saat Anda mengetahui indeks elemen, tetapi terkadang Anda ingin elemen array mana pun yang cocok dengan kriteria Anda. Anda dapat mengembalikan elemen yang cocok dengan
> db.users.find({"username" : "joe"})
08-operator. Mengingat contoh blog di atas, Anda bisa mendapatkan kembali komentar Bob

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_6

Perhatikan bahwa ini hanya mengembalikan kecocokan pertama untuk setiap dokumen. jika Bob telah meninggalkan banyak komentar pada posting ini, hanya yang pertama di array "

> db.users.find({"username" : "joe"})
09" yang akan dikembalikan

Interaksi kueri larik dan rentang

Skalar (elemen non-array) dalam dokumen harus cocok dengan setiap klausa kriteria kueri. Misalnya, jika Anda menanyakan

> db.users.find({"username" : "joe"})
10, "
> db.users.find({"age" : 27})
63" harus lebih besar dari 10 dan kurang dari 20. Namun, jika bidang "
> db.users.find({"age" : 27})
63" dokumen adalah larik, dokumen cocok jika ada elemen "
> db.users.find({"age" : 27})
63" yang cocok dengan setiap bagian kriteria tetapi setiap klausa kueri dapat cocok dengan elemen larik yang berbeda

Cara terbaik untuk memahami perilaku ini adalah dengan melihat contoh. Misalkan kita memiliki dokumen-dokumen berikut

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_7

Jika kami ingin menemukan semua dokumen dengan "

> db.users.find({"age" : 27})
63" antara 10 dan 20, seseorang mungkin secara naif menyusun kueri sebagai
> db.users.find({"username" : "joe"})
15 dan berharap untuk mendapatkan kembali satu dokumen.
> db.users.find({"username" : "joe"})
_16. Namun, menjalankan ini, kami mendapatkan dua

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_8

Baik 5 maupun 25 tidak antara 10 dan 20, tetapi dokumen dikembalikan karena 25 cocok dengan klausa pertama (lebih besar dari 10) dan 5 cocok dengan klausa kedua (kurang dari 20)

Ini membuat kueri rentang terhadap array pada dasarnya tidak berguna. rentang akan cocok dengan larik multi-elemen apa pun. Ada beberapa cara untuk mendapatkan perilaku yang diharapkan

Pertama, Anda dapat menggunakan "

> db.users.find({"username" : "joe"})
_17" untuk memaksa MongoDB membandingkan kedua klausa dengan elemen array tunggal. Namun, tangkapannya adalah "
> db.users.find({"username" : "joe"})
_17" tidak akan cocok dengan elemen non-array

> db.users.find({}, {"username" : 1, "email" : 1})
{
    "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
    "username" : "joe",
    "email" : "[email protected]"
}
_9

Dokumen

> db.users.find({"username" : "joe"})
16 tidak lagi cocok dengan kueri, karena kolom "
> db.users.find({"age" : 27})
63" bukan array

Jika Anda memiliki indeks pada bidang yang Anda kueri (lihat Bab 5), Anda dapat menggunakan

> db.users.find({"username" : "joe"})
21 dan
> db.users.find({"username" : "joe"})
22 untuk membatasi rentang indeks yang dilalui oleh kueri ke nilai "
> db.users.find({"username" : "joe"})
23" dan "
> db.users.find({"username" : "joe"})
24" Anda

> db.users.find({}, {"fatal_weakness" : 0})
_0

Sekarang ini hanya akan melintasi indeks dari 10 sampai 20, hilang 5 dan 25 entri. Anda hanya dapat menggunakan

> db.users.find({"username" : "joe"})
21 dan
> db.users.find({"username" : "joe"})
22 ketika Anda memiliki indeks pada bidang yang Anda minta, dan Anda harus meneruskan semua bidang indeks ke
> db.users.find({"username" : "joe"})
21 dan
> db.users.find({"username" : "joe"})
22

Menggunakan

> db.users.find({"username" : "joe"})
_21 dan
> db.users.find({"username" : "joe"})
22 saat menanyakan rentang pada dokumen yang mungkin menyertakan array umumnya merupakan ide yang bagus. jika Anda melihat batas indeks untuk kueri "
> db.users.find({"username" : "joe"})
23“/”
> db.users.find({"username" : "joe"})
24" di atas array, Anda dapat melihat bahwa itu sangat tidak efisien. Ini pada dasarnya menerima nilai apa pun, sehingga akan mencari setiap entri indeks, bukan hanya yang ada dalam rentang

Melakukan kueri pada Dokumen yang Disematkan

Ada dua cara menanyakan dokumen yang disematkan. melakukan kueri untuk seluruh dokumen atau meminta pasangan kunci/nilai individualnya

Membuat kueri untuk seluruh dokumen yang disematkan bekerja secara identik dengan kueri normal. Misalnya, jika kita memiliki dokumen yang terlihat seperti ini

> db.users.find({}, {"fatal_weakness" : 0})
_1

kita dapat menanyakan seseorang bernama Joe Schmoe dengan yang berikut ini

> db.users.find({}, {"fatal_weakness" : 0})
_2

Namun, kueri untuk subdokumen lengkap harus sama persis dengan subdokumen. Jika Joe memutuskan untuk menambahkan bidang nama tengah, tiba-tiba kueri ini tidak berfungsi lagi; . Jenis kueri ini juga sensitif terhadap pesanan.

> db.users.find({"username" : "joe"})
_33 tidak akan cocok

Jika memungkinkan, biasanya merupakan ide yang baik untuk meminta hanya satu atau beberapa kunci tertentu dari dokumen yang disematkan. Kemudian, jika skema Anda berubah, semua kueri Anda tidak akan tiba-tiba rusak karena tidak lagi sama persis. Anda dapat meminta kunci yang disematkan menggunakan notasi titik

> db.users.find({}, {"fatal_weakness" : 0})
_3

Sekarang, jika Joe menambahkan lebih banyak kunci, kueri ini akan tetap cocok dengan nama depan dan belakangnya

Notasi titik ini adalah perbedaan utama antara dokumen kueri dan jenis dokumen lainnya. Dokumen kueri dapat berisi titik-titik, yang artinya “mencapai dokumen yang disematkan. Notasi titik juga menjadi alasan dokumen yang akan disisipkan tidak dapat memuat. karakter. Seringkali orang mengalami batasan ini saat mencoba menyimpan URL sebagai kunci. Salah satu cara untuk menyiasatinya adalah dengan selalu melakukan penggantian global sebelum memasukkan atau setelah mengambil, mengganti karakter titik yang tidak sah di URL

Pencocokan dokumen tersemat bisa menjadi sedikit rumit karena struktur dokumen menjadi lebih rumit. Misalnya, kita menyimpan postingan blog dan ingin mencari komentar dari Joe yang mendapat skor minimal 5. Kita bisa memodelkan pos sebagai berikut

> db.users.find({}, {"fatal_weakness" : 0})
_4

Sekarang, kami tidak dapat melakukan kueri menggunakan ________10______34. Kecocokan dokumen tersemat harus cocok dengan seluruh dokumen, dan ini tidak cocok dengan kunci

> db.users.find({"username" : "joe"})
35. Itu juga tidak akan berhasil untuk melakukan
> db.users.find({"username" : "joe"})
36, karena kriteria penulis dapat cocok dengan komentar yang berbeda dari kriteria skor. Artinya, itu akan mengembalikan dokumen yang ditunjukkan di atas. itu akan cocok dengan
> db.users.find({"username" : "joe"})
_37 di komentar pertama dan
> db.users.find({"username" : "joe"})
38 di komentar kedua

Untuk mengelompokkan kriteria dengan benar tanpa harus menentukan setiap kunci, gunakan

> db.users.find({"username" : "joe"})
39. Kondisional yang diberi nama samar ini memungkinkan Anda untuk menentukan sebagian kriteria agar cocok dengan satu dokumen yang disematkan dalam sebuah larik. Permintaan yang benar terlihat seperti ini

> db.users.find({}, {"fatal_weakness" : 0})
_5

> db.users.find({"username" : "joe"})
_39 memungkinkan kita untuk "mengelompokkan" kriteria kita. Dengan demikian, ini hanya diperlukan bila Anda memiliki lebih dari satu kunci yang ingin Anda cocokkan dalam dokumen tersemat

Pasangan kunci/nilai adalah cara kueri yang cukup ekspresif, tetapi ada beberapa kueri yang tidak dapat mereka wakili. Untuk kueri yang tidak dapat dilakukan dengan cara lain, ada

> db.users.find({"username" : "joe"})
41 klausa, yang memungkinkan Anda untuk mengeksekusi JavaScript arbitrer sebagai bagian dari kueri Anda. Ini memungkinkan Anda melakukan (hampir) apa saja dalam kueri. Demi keamanan, penggunaan klausa "
> db.users.find({"username" : "joe"})
_42" harus sangat dibatasi atau dihilangkan. Pengguna akhir tidak boleh diizinkan untuk mengeksekusi klausa "________10______42" yang sewenang-wenang

Kasus paling umum untuk menggunakan "

> db.users.find({"username" : "joe"})
_42" adalah membandingkan nilai untuk dua kunci dalam dokumen. Misalnya, misalkan kita memiliki dokumen yang terlihat seperti ini

> db.users.find({}, {"fatal_weakness" : 0})
_6

Kami ingin mengembalikan dokumen dengan dua bidang yang sama. Misalnya, di dokumen kedua,

> db.users.find({"username" : "joe"})
_45 dan
> db.users.find({"username" : "joe"})
46 memiliki nilai yang sama, jadi kami ingin dokumen itu dikembalikan. Tidak mungkin MongoDB akan memiliki $-conditional untuk ini, jadi kita dapat menggunakan klausa
> db.users.find({"username" : "joe"})
41 untuk melakukannya dengan JavaScript

> db.users.find({}, {"fatal_weakness" : 0})
_7

Jika fungsi mengembalikan

> db.users.find({"age" : 27})
37, dokumen akan menjadi bagian dari kumpulan hasil;

> db.users.find({"username" : "joe"})
_41 pertanyaan tidak boleh digunakan kecuali benar-benar diperlukan. mereka jauh lebih lambat daripada kueri biasa. Setiap dokumen harus dikonversi dari BSON ke objek JavaScript dan kemudian dijalankan melalui ekspresi
> db.users.find({"username" : "joe"})
41. Indeks juga tidak dapat digunakan untuk memenuhi ________10______41. Oleh karena itu, Anda harus menggunakan
> db.users.find({"username" : "joe"})
_41 hanya jika tidak ada cara lain untuk melakukan kueri. Anda dapat mengurangi penalti dengan menggunakan filter kueri lain yang dikombinasikan dengan
> db.users.find({"username" : "joe"})
41. Jika memungkinkan, indeks akan digunakan untuk memfilter berdasarkan klausa non-
> db.users.find({"username" : "joe"})
42;

Cara lain untuk melakukan kueri kompleks adalah dengan menggunakan salah satu alat agregasi, yang dibahas di Bab 7

Anda harus sangat berhati-hati dengan keamanan saat menjalankan JavaScript di server. Jika dilakukan secara tidak benar, JavaScript sisi server rentan terhadap serangan injeksi yang serupa dengan yang terjadi di database relasional. Namun, dengan mengikuti aturan tertentu seputar menerima input, Anda dapat menggunakan JavaScript dengan aman. Sebagai alternatif, Anda dapat mematikan eksekusi JavaScript sekaligus dengan menjalankan mongod dengan opsi

> db.users.find({"username" : "joe"})
57

Masalah keamanan dengan JavaScript semuanya terkait dengan menjalankan program yang disediakan pengguna di server. Anda ingin menghindari melakukan itu, jadi pastikan Anda tidak menerima input pengguna dan meneruskannya langsung ke mongod. Misalnya, Anda ingin mencetak “Halo,

> db.users.find({"username" : "joe"})
58. ”, di mana
> db.users.find({"username" : "joe"})
_58 disediakan oleh pengguna. Pendekatan naif mungkin untuk menulis fungsi JavaScript seperti berikut ini

> db.users.find({}, {"fatal_weakness" : 0})
_8

Jika

> db.users.find({"username" : "joe"})
_58 adalah variabel yang ditentukan pengguna, itu bisa berupa string
> db.users.find({"username" : "joe"})
61, yang akan mengubah kode menjadi ini

> db.users.find({}, {"fatal_weakness" : 0})
_9

Sekarang, jika Anda menjalankan kode ini, seluruh database Anda akan dihapus

Untuk mencegah hal ini, Anda harus menggunakan cakupan untuk meneruskan nama. Di Python, misalnya, ini terlihat seperti ini

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
0

Sekarang basis data akan mencetak ini tanpa membahayakan

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
1

Sebagian besar driver memiliki tipe khusus untuk mengirimkan kode ke database, karena kode sebenarnya dapat berupa gabungan dari string dan cakupan. Cakupan adalah dokumen yang memetakan nama variabel ke nilai. Pemetaan ini menjadi cakupan lokal untuk fungsi JavaScript yang dijalankan. Jadi, dalam contoh di atas, fungsi akan memiliki akses ke variabel yang disebut

> db.users.find({"username" : "joe"})
62, yang nilainya adalah string yang diberikan pengguna

Catatan

Shell tidak memiliki tipe kode yang menyertakan ruang lingkup;

Database mengembalikan hasil dari

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2 menggunakan kursor. Implementasi kursor sisi-klien umumnya memungkinkan Anda untuk mengontrol banyak hal tentang hasil akhir kueri. Anda dapat membatasi jumlah hasil, melewatkan beberapa hasil, mengurutkan hasil dengan kombinasi tombol apa pun ke segala arah, dan melakukan sejumlah operasi hebat lainnya

Untuk membuat kursor dengan shell, masukkan beberapa dokumen ke dalam koleksi, lakukan kueri padanya, dan tetapkan hasilnya ke variabel lokal (variabel yang ditentukan dengan

> db.users.find({"username" : "joe"})
64 bersifat lokal). Di sini, kami membuat koleksi yang sangat sederhana dan menanyakannya, menyimpan hasilnya dalam variabel
> db.users.find({"username" : "joe"})
65

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
2

Keuntungan melakukan ini adalah Anda dapat melihat satu hasil pada satu waktu. Jika Anda menyimpan hasilnya dalam variabel global atau tanpa variabel sama sekali, shell MongoDB akan secara otomatis mengulang dan menampilkan beberapa dokumen pertama. Inilah yang telah kami lihat sampai saat ini, dan sering kali ini adalah perilaku yang Anda inginkan untuk melihat apa yang ada dalam koleksi, tetapi bukan untuk melakukan pemrograman yang sebenarnya dengan shell

Untuk mengulangi hasil, Anda dapat menggunakan metode

> db.users.find({"username" : "joe"})
66 pada kursor. Anda dapat menggunakan
> db.users.find({"username" : "joe"})
_67 untuk memeriksa apakah ada hasil lain. Sebuah loop khas melalui hasil terlihat seperti berikut ini

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
3

> db.users.find({"username" : "joe"})
_68 memeriksa apakah hasil berikutnya ada, dan
> db.users.find({"username" : "joe"})
69 mengambilnya

Kelas

> db.users.find({"username" : "joe"})
_65 juga mengimplementasikan antarmuka iterator JavaScript, sehingga Anda dapat menggunakannya dalam loop
> db.users.find({"username" : "joe"})
71

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
4

Saat Anda memanggil

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
_2, shell tidak langsung menanyakan database. Itu menunggu hingga Anda mulai meminta hasil untuk mengirim kueri, yang memungkinkan Anda untuk mengaitkan opsi tambahan ke kueri sebelum dilakukan. Hampir setiap metode pada objek kursor mengembalikan kursor itu sendiri sehingga Anda dapat merangkai opsi dalam urutan apa pun. Misalnya, semua hal berikut ini setara

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
5

Pada titik ini, kueri belum dieksekusi. Semua fungsi ini hanya membuat kueri. Sekarang, misalkan kita memanggil yang berikut ini

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
6

Pada titik ini, kueri akan dikirim ke server. Shell mengambil 100 hasil pertama atau 4 MB hasil pertama (mana yang lebih kecil) sekaligus sehingga panggilan berikutnya ke

> db.users.find({"username" : "joe"})
66 atau
> db.users.find({"username" : "joe"})
67 tidak perlu melakukan perjalanan ke server. Setelah klien menjalankan kumpulan hasil pertama, shell akan kembali menghubungi database dan meminta lebih banyak hasil dengan permintaan getMore. permintaan getMore pada dasarnya berisi pengidentifikasi untuk kueri dan menanyakan database jika ada hasil lagi, mengembalikan batch berikutnya jika ada. Proses ini berlanjut hingga kursor habis dan semua hasil dikembalikan

Opsi kueri yang paling umum adalah membatasi jumlah hasil yang dikembalikan, melewatkan sejumlah hasil, dan menyortir. Semua opsi ini harus ditambahkan sebelum kueri dikirim ke database

Untuk menetapkan batas, rangkai fungsi

> db.users.find({"username" : "joe"})
_75 ke panggilan Anda ke
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2. Misalnya, untuk hanya mengembalikan tiga hasil, gunakan ini

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
7

Jika terdapat kurang dari tiga dokumen yang cocok dengan kueri Anda dalam kumpulan, hanya jumlah dokumen yang cocok yang akan dikembalikan;

> db.users.find({"username" : "joe"})
_78 bekerja mirip dengan
> db.users.find({"username" : "joe"})
75

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
8

Ini akan melewatkan tiga dokumen pencocokan pertama dan mengembalikan sisa pencocokan. Jika ada kurang dari tiga dokumen dalam koleksi Anda, itu tidak akan mengembalikan dokumen apa pun

> db.users.find({"username" : "joe"})
_80 mengambil objek. satu set pasangan kunci/nilai di mana kuncinya adalah nama kunci dan nilainya adalah arah pengurutan. Arah pengurutan bisa 1 (naik) atau −1 (turun). Jika beberapa kunci diberikan, hasilnya akan diurutkan dalam urutan tersebut. Misalnya, untuk mengurutkan hasil dengan
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
_8 menaik dan
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
7 menurun, kita lakukan hal berikut

> db.users.find({}, {"username" : 1, "_id" : 0})
{
    "username" : "joe",
}
_9

Ketiga cara ini dapat digabungkan. Hal ini sering berguna untuk pagination. Misalnya, Anda menjalankan toko online dan seseorang menelusuri mp3. Jika Anda menginginkan 50 hasil per halaman yang diurutkan berdasarkan harga dari tinggi ke rendah, Anda dapat melakukan hal berikut

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_0

Jika orang itu mengklik Halaman Berikutnya untuk melihat lebih banyak hasil, Anda cukup menambahkan lompatan ke kueri, yang akan melewati 50 kecocokan pertama (yang sudah dilihat pengguna di halaman 1)

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_1

Namun, lompatan besar tidak terlalu bagus;

MongoDB memiliki hierarki tentang bagaimana perbandingan tipe. Terkadang Anda akan memiliki satu kunci dengan beberapa jenis. misalnya, bilangan bulat dan boolean, atau string dan nol. Jika Anda melakukan pengurutan pada kunci dengan campuran jenis, ada urutan yang telah ditentukan sebelumnya yang akan disortir. Dari nilai terkecil hingga terbesar, urutannya adalah sebagai berikut

  1. Nilai minimal

  2. > db.users.find({"age" : 27})
    _67

  3. Angka (bilangan bulat, panjang, ganda)

  4. String

  5. Objek/dokumen

  6. Himpunan

  7. Data biner

  8. ID objek

  9. Boolean

  10. Tanggal

  11. Stempel waktu

  12. Ekspresi reguler

  13. Nilai maksimum

Menggunakan

> db.users.find({"username" : "joe"})
_78 untuk sejumlah kecil dokumen tidak masalah. Untuk sejumlah besar hasil,
> db.users.find({"username" : "joe"})
_78 bisa lambat, karena harus menemukan lalu membuang semua hasil yang dilewati. Sebagian besar database menyimpan lebih banyak metadata dalam indeks untuk membantu melewati, tetapi MongoDB belum mendukung ini, jadi lompatan besar harus dihindari. Seringkali Anda dapat menghitung kueri berikutnya berdasarkan hasil dari kueri sebelumnya

Menomori hasil tanpa melewati

Cara termudah untuk melakukan paginasi adalah mengembalikan halaman pertama hasil menggunakan batas dan kemudian mengembalikan setiap halaman berikutnya sebagai offset dari awal

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_2

Namun, bergantung pada kueri Anda, biasanya Anda dapat menemukan cara membuat nomor halaman tanpa

> db.users.find({"username" : "joe"})
78s. Misalnya, kita ingin menampilkan dokumen dalam urutan menurun berdasarkan
> db.users.find({"username" : "joe"})
87. Kita bisa mendapatkan halaman pertama hasil dengan yang berikut ini

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_3

Kemudian, dengan asumsi tanggalnya unik, kita dapat menggunakan nilai

> db.users.find({"username" : "joe"})
87 dari dokumen terakhir sebagai kriteria untuk mengambil halaman berikutnya

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_4

Sekarang kueri tidak perlu menyertakan ________10______78

Menemukan dokumen acak

Satu masalah yang cukup umum adalah bagaimana mendapatkan dokumen acak dari sebuah koleksi. Solusi naif (dan lambat) adalah menghitung jumlah dokumen dan kemudian melakukan

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2, melewatkan sejumlah dokumen acak antara 0 dan ukuran koleksi

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_5

Sebenarnya sangat tidak efisien untuk mendapatkan elemen acak dengan cara ini. Anda harus menghitung (yang bisa mahal jika Anda menggunakan kriteria), dan melewatkan sejumlah besar elemen dapat menghabiskan waktu

Dibutuhkan sedikit pemikiran, tetapi jika Anda tahu Anda akan mencari elemen acak pada koleksi, ada cara yang jauh lebih efisien untuk melakukannya. Triknya adalah dengan menambahkan kunci acak ekstra ke setiap dokumen saat dimasukkan. Misalnya, jika kita menggunakan shell, kita dapat menggunakan fungsi

> db.users.find({"username" : "joe"})
91 (yang membuat angka acak antara 0 dan 1)

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_6

Sekarang, ketika kita ingin menemukan dokumen acak dari koleksi, kita dapat menghitung angka acak dan menggunakannya sebagai kriteria kueri, alih-alih melakukan

> db.users.find({"username" : "joe"})
78

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_7

Ada kemungkinan kecil bahwa

> db.users.find({"username" : "joe"})
_93 akan lebih besar daripada nilai
> db.users.find({"username" : "joe"})
94 mana pun dalam koleksi, dan tidak ada hasil yang akan dikembalikan. Kami dapat mencegah hal ini hanya dengan mengembalikan dokumen ke arah lain

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_8

Jika tidak ada dokumen dalam koleksi, teknik ini akan mengembalikan

> db.users.find({"age" : 27})
67, yang masuk akal

Teknik ini dapat digunakan dengan kueri kompleks yang sewenang-wenang; . Misalnya, jika kita ingin menemukan tukang ledeng acak di California, kita dapat membuat indeks pada

> db.users.find({"username" : "joe"})
96,
> db.users.find({"username" : "joe"})
97, dan
> db.users.find({"username" : "joe"})
94

> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
_9

Ini memungkinkan kami menemukan hasil acak dengan cepat (lihat Bab 5 untuk informasi lebih lanjut tentang pengindeksan)

Ada dua jenis kueri. dibungkus dan polos. Permintaan biasa adalah seperti ini

> db.stock.find({"in_stock" : 0})
0

Ada beberapa opsi yang "membungkus" kueri. Sebagai contoh, misalkan kita melakukan pengurutan

> db.stock.find({"in_stock" : 0})
1

Alih-alih mengirim

> db.users.find({"username" : "joe"})
_99 ke database sebagai kueri, kueri dibungkus dalam dokumen yang lebih besar. Shell mengonversi kueri dari
> db.users.find({"username" : "joe"})
_99 menjadi
> db.users.find({"username" : "joe", "age" : 27})
01

Sebagian besar driver menyediakan pembantu untuk menambahkan opsi sewenang-wenang ke kueri. Opsi bermanfaat lainnya termasuk yang berikut ini

> db.users.find({"username" : "joe", "age" : 27})
_02

Tentukan jumlah maksimum dokumen yang harus dipindai untuk kueri

> db.stock.find({"in_stock" : 0})
2

Ini bisa berguna jika Anda ingin kueri tidak memakan waktu terlalu lama tetapi tidak yakin berapa banyak koleksi yang perlu dipindai. Ini akan membatasi hasil Anda pada apa pun yang ditemukan di bagian koleksi yang dipindai (mis. e. , Anda mungkin melewatkan dokumen lain yang cocok)

> db.users.find({"username" : "joe", "age" : 27})
_03

Mulai kriteria untuk membuat kueri.

> db.users.find({"username" : "joe", "age" : 27})
_04 harus sama persis dengan kunci indeks yang digunakan untuk kueri. Ini memaksa indeks yang diberikan untuk digunakan untuk kueri

Ini digunakan secara internal dan umumnya Anda harus menggunakan

> db.users.find({"age" : 27})
17 alih-alih
> db.users.find({"username" : "joe", "age" : 27})
06. Anda dapat menggunakan
> db.users.find({"username" : "joe", "age" : 27})
_06 untuk memaksakan batas bawah pada pemindaian indeks, yang mungkin berguna untuk kueri kompleks

> db.users.find({"username" : "joe", "age" : 27})
_08

Kriteria akhir untuk kueri.

> db.users.find({"username" : "joe", "age" : 27})
_04 harus sama persis dengan kunci indeks yang digunakan untuk kueri. Ini memaksa indeks yang diberikan untuk digunakan untuk kueri

Jika ini digunakan secara internal, umumnya Anda harus menggunakan

> db.users.find({"age" : 27})
15 alih-alih
> db.users.find({"username" : "joe", "age" : 27})
11. Anda dapat menggunakan
> db.users.find({"username" : "joe", "age" : 27})
_11 untuk memaksakan batas pada pemindaian indeks, yang mungkin berguna untuk kueri kompleks

> db.users.find({"username" : "joe", "age" : 27})
_13

Menambahkan bidang "

> db.users.find({"username" : "joe", "age" : 27})
14" ke hasil yang menunjukkan lokasi hasil tertentu di disk. Sebagai contoh

> db.stock.find({"in_stock" : 0})
3

Nomor file menunjukkan di file mana dokumen itu berada. Dalam hal ini, jika kita menggunakan database pengujian, dokumen sedang dalam pengujian. 2. Bidang kedua memberikan offset byte dari setiap dokumen di dalam file

Mendapatkan Hasil yang Konsisten

Cara yang cukup umum untuk memproses data adalah dengan menariknya keluar dari MongoDB, mengubahnya dengan cara tertentu, lalu menyimpannya kembali

> db.stock.find({"in_stock" : 0})
4

Ini bagus untuk sejumlah kecil hasil, tetapi MongoDB dapat mengembalikan hasil yang sama beberapa kali untuk kumpulan hasil yang besar. Untuk mengetahui alasannya, bayangkan bagaimana dokumen disimpan. Anda dapat membayangkan koleksi sebagai daftar dokumen yang terlihat seperti itu. Kepingan salju mewakili dokumen, karena setiap dokumen itu indah dan unik

Mongodb menemukan _id lebih besar dari

Gambar 4-1. Koleksi sedang ditanyakan

Sekarang, saat kita melakukan

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
2, kursor mulai mengembalikan hasil dari awal koleksi dan bergerak ke kanan. Program Anda mengambil 100 dokumen pertama dan memprosesnya. Saat Anda menyimpannya kembali ke database, jika dokumen tidak memiliki padding yang tersedia untuk memperbesar ukuran barunya, seperti di , dokumen perlu dipindahkan. Biasanya, dokumen akan dipindahkan ke akhir koleksi ()

Mongodb menemukan _id lebih besar dari

Gambar 4-2. Dokumen yang diperbesar mungkin tidak muat di tempatnya sebelumnya

Mongodb menemukan _id lebih besar dari

Gambar 4-3. MongoDB merelokasi dokumen yang diperbarui yang tidak sesuai dengan posisi aslinya

Sekarang program kami terus mengambil kumpulan dokumen. Ketika mendekati akhir, itu akan mengembalikan dokumen yang dipindahkan lagi ()

Mongodb menemukan _id lebih besar dari

Gambar 4-4. Kursor dapat mengembalikan dokumen yang dipindahkan ini lagi di batch berikutnya

Solusi untuk masalah ini adalah memotret kueri Anda. Jika Anda menambahkan opsi, kueri akan dijalankan dengan menelusuri indeks "________14______16", yang menjamin bahwa Anda hanya akan mengembalikan setiap dokumen satu kali. Misalnya, alih-alih

> db.users.find({"username" : "joe", "age" : 27})
_17, Anda akan berlari

> db.stock.find({"in_stock" : 0})
5

Snapshotting membuat kueri lebih lambat, jadi gunakan kueri snapshot hanya jika diperlukan. Misalnya, mongodump (utilitas pencadangan yang dibahas di Bab 22) menggunakan kueri snapshot secara default

Semua kueri yang mengembalikan satu batch hasil secara efektif di-snapshot. Ketidakkonsistenan muncul hanya ketika koleksi berubah di bawah kursor saat menunggu untuk mendapatkan kumpulan hasil lainnya

Ada dua sisi kursor. kursor yang menghadap ke klien dan kursor basis data yang diwakili oleh sisi klien. Kami telah berbicara tentang sisi klien sampai sekarang, tetapi kami akan melihat secara singkat apa yang terjadi di server

Di sisi server, kursor memakan memori dan sumber daya. Setelah kursor kehabisan hasil atau klien mengirim pesan yang memberitahukannya untuk mati, database dapat membebaskan sumber daya yang digunakannya. Membebaskan sumber daya ini memungkinkan database menggunakannya untuk hal lain, yang bagus, jadi kami ingin memastikan bahwa kursor dapat dibebaskan dengan cepat (sesuai alasan)

Ada beberapa kondisi yang dapat menyebabkan kematian (dan pembersihan selanjutnya) kursor. Pertama, saat kursor selesai mengulangi hasil yang cocok, kursor akan membersihkan dirinya sendiri. Cara lain adalah, ketika kursor keluar dari ruang lingkup di sisi klien, driver mengirim pesan khusus ke database untuk memberi tahu bahwa itu dapat mematikan kursor itu. Terakhir, bahkan jika pengguna belum mengulangi semua hasil dan kursor masih dalam cakupan, setelah 10 menit tidak aktif, kursor database akan secara otomatis "mati. ” Dengan cara ini, jika klien mogok atau bermasalah, MongoDB tidak akan ditinggalkan dengan ribuan kursor terbuka

"Death by timeout" ini biasanya merupakan perilaku yang diinginkan. sangat sedikit aplikasi yang mengharapkan penggunanya untuk duduk-duduk selama beberapa menit sambil menunggu hasil. Namun, terkadang Anda mungkin tahu bahwa Anda membutuhkan kursor untuk bertahan lama. Dalam hal ini, banyak driver telah menerapkan fungsi yang disebut

> db.users.find({"username" : "joe", "age" : 27})
18, atau mekanisme serupa, yang memberi tahu database untuk tidak kehabisan waktu kursor. Jika Anda menonaktifkan batas waktu kursor, Anda harus mengulangi semua hasilnya atau mematikannya untuk memastikannya ditutup. Jika tidak, itu akan duduk di database memonopoli sumber daya sampai server dimulai ulang

Ada satu jenis kueri yang sangat khusus yang disebut perintah basis data. Kami telah membahas membuat, memperbarui, menghapus, dan menemukan dokumen. Perintah basis data melakukan "segalanya", mulai dari tugas administratif seperti mematikan server dan mengkloning basis data hingga menghitung dokumen dalam kumpulan dan melakukan agregasi

Perintah disebutkan di seluruh teks ini, karena berguna untuk manipulasi data, administrasi, dan pemantauan. Misalnya, menjatuhkan koleksi dilakukan melalui perintah database "________14______19".

> db.stock.find({"in_stock" : 0})
6

Anda mungkin lebih familiar dengan shell helper, yang membungkus perintah dan menyediakan antarmuka yang lebih sederhana

> db.stock.find({"in_stock" : 0})
7

Seringkali Anda hanya bisa menggunakan shell helper, tetapi mengetahui perintah yang mendasarinya dapat membantu jika Anda terjebak pada kotak dengan versi lama dari shell dan terhubung ke versi baru dari database. shell mungkin tidak memiliki pembungkus untuk perintah basis data baru, tetapi Anda masih dapat menjalankannya dengan

> db.users.find({"username" : "joe", "age" : 27})
20

Kita telah melihat beberapa perintah di bab sebelumnya;

> db.stock.find({"in_stock" : 0})
8

Di bagian ini, kita akan melihat lebih dekat pada perintah untuk melihat dengan tepat apa itu dan bagaimana penerapannya. Kami juga akan menjelaskan beberapa perintah paling berguna yang didukung oleh MongoDB. Anda dapat melihat semua perintah dengan menjalankan perintah ________14______22

Perintah basis data selalu mengembalikan dokumen yang berisi kunci

> db.users.find({"username" : "joe", "age" : 27})
23. Jika
> db.users.find({"username" : "joe", "age" : 27})
_23 adalah nilai sebenarnya (
> db.users.find({"username" : "joe", "age" : 27})
25,
> db.users.find({"username" : "joe", "age" : 27})
26, atau
> db.users.find({"age" : 27})
37), perintah berhasil;

Jika

> db.users.find({"username" : "joe", "age" : 27})
_23 adalah
> db.users.find({"username" : "joe", "age" : 27})
30 maka kunci tambahan akan hadir,
> db.users.find({"username" : "joe", "age" : 27})
31. Nilai
> db.users.find({"username" : "joe", "age" : 27})
_31 adalah string yang menjelaskan mengapa perintah gagal. Sebagai contoh, mari kita coba menjalankan perintah
> db.users.find({"username" : "joe", "age" : 27})
19 lagi, pada koleksi yang dijatuhkan di bagian sebelumnya

> db.stock.find({"in_stock" : 0})
_9

Perintah di MongoDB diimplementasikan sebagai tipe kueri khusus yang dilakukan pada koleksi $cmd.

> db.users.find({"username" : "joe", "age" : 27})
_34 hanya mengambil dokumen perintah dan melakukan kueri yang setara, jadi drop call kami menjadi sebagai berikut

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
0

Saat server MongoDB mendapatkan kueri pada koleksi $cmd, ia menanganinya menggunakan logika khusus, bukan kode normal untuk menangani kueri. Hampir semua driver MongoDB menyediakan metode pembantu seperti

> db.users.find({"username" : "joe", "age" : 27})
34 untuk menjalankan perintah, tetapi perintah selalu dapat dijalankan menggunakan kueri sederhana

Beberapa perintah memerlukan akses administrator dan harus dijalankan di database admin. Jika perintah seperti itu dijalankan di database lain, itu akan mengembalikan kesalahan ________14______36. Jika Anda sedang mengerjakan database lain dan Anda perlu menjalankan perintah admin, Anda dapat menggunakan fungsi ________14______37, bukan

> db.users.find({"username" : "joe", "age" : 27})
34

> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
_1

Perintah adalah salah satu dari sedikit tempat yang sensitif terhadap urutan bidang. nama perintah harus selalu menjadi bidang pertama dalam perintah. Jadi,

> db.users.find({"username" : "joe", "age" : 27})
_39 akan berhasil, tetapi
> db.users.find({"username" : "joe", "age" : 27})
40 tidak akan berhasil

Bagaimana menemukan lebih besar daripada di MongoDB?

MongoDB menyediakan berbagai jenis operator perbandingan dan lebih besar dari sama dengan operator($gte) adalah salah satunya. Operator ini digunakan untuk memilih dokumen-dokumen yang nilai bidangnya lebih besar dari sama dengan(>=) nilai yang diberikan. Anda dapat menggunakan operator ini dalam metode (seperti, find(), update(), dll. )

Bagaimana Anda menemukan kurang dari dan lebih besar dari di MongoDB?

Anda dapat menggunakan operator berikut di MongoDB untuk menjalankan kueri lebih besar atau lebih kecil dari. .
$lt. Kurang dari
$ lte. Kurang dari atau sama
$gt. Lebih besar dari
$gte. Lebih besar dari atau sama

Bagaimana cara menanyakan lebih besar dari tanggal di MongoDB?

MongoDB. Cara Membuat Kueri dengan Rentang Tanggal - Statologi temukan ( { hari. { $gt. ISODate ("21-01-2020"), $lt. ISODate ("2020-01-24") } }) Permintaan khusus ini akan mengembalikan semua dokumen dalam koleksi di mana bidang "hari" lebih besar dari 21-01-2020 dan kurang dari 2020 .

Haruskah saya menggunakan _id di MongoDB?

Field _id MongoDB sangat mendasar untuk setiap koleksi di MongoDB , dan, secara default, ia memiliki beberapa properti berguna yang dapat dimanfaatkan pengguna saat mengetahui cara _id dibuat.