Untuk tutorial ini kita akan menggunakan official dummy dataset
, yang berisi banyak dokumen restoran dari seluruh wilayah New York.
Berikut adalah contoh struktur dokumen dasar dalam koleksi ini, menggunakan .findOne()
metode:
> db.restaurants.findOne()
{
"_id" : ObjectId("56c651e7d84ccfde319961af"),
"address" : {
"building" : "469",
"coord" : [
-73.961704,
40.662942
],
"street" : "Flatbush Avenue",
"zipcode" : "11225"
},
"borough" : "Brooklyn",
"cuisine" : "Hamburgers",
"grades" : [
{
"date" : ISODate("2014-12-30T00:00:00Z"),
"grade" : "A",
"score" : 8
},
{
"date" : ISODate("2014-07-01T00:00:00Z"),
"grade" : "B",
"score" : 23
},
{
"date" : ISODate("2013-04-30T00:00:00Z"),
"grade" : "A",
"score" : 12
},
{
"date" : ISODate("2012-05-08T00:00:00Z"),
"grade" : "A",
"score" : 12
}
],
"name" : "Wendy'S",
"restaurant_id" : "30112340"
}
Kekuatan Menemukan
Bagian terpenting dari teka-teki saat mencari dalam koleksi MongoDB adalah db.collection.find()
yang sederhana namun fleksibel. metode.
Dengan .find()
, Anda dapat dengan mudah mengkueri kumpulan dokumen, dengan meneruskan beberapa parameter sederhana, dan mengembalikan cursor
. Sebuah cursor
hanyalah kumpulan hasil dan dapat diulang untuk memanipulasi atau menggunakan dokumen yang ditunjuk oleh cursor
.
Sebagai contoh sederhana dari .find()
metode dalam tindakan, kami akan mencoba menemukan semua restoran di koleksi kami yang server Hamburgers
sebagai cuisine
their :
>db.restaurants.find( { cuisine: "Hamburgers" } )
{ "_id" : ObjectId("56c651e7d84ccfde319961af"), "address" : { "building" : "469", "coord" : [ -73.961704, 40.662942 ], "street" : "Flatbush Avenue", "zipcode" : "11225" }, "borough" : "Brooklyn", "cuisine" : "Hamburgers", "grades" : [ { "date" : ISODate("2014-12-30T00:00:00Z"), "grade" : "A", "score" : 8 }, { "date" : ISODate("2014-07-01T00:00:00Z"), "grade" : "B", "score" : 23 }, { "date" : ISODate("2013-04-30T00:00:00Z"), "grade" : "A", "score" : 12 }, { "date" : ISODate("2012-05-08T00:00:00Z"), "grade" : "A", "score" : 12 } ], "name" : "Wendy'S", "restaurant_id" : "30112340" }
...
Kumpulan hasil cukup besar, jadi pengukuran yang lebih baik untuk contoh pengujian kami adalah dengan merangkai .count()
metode ke .find()
untuk melihat berapa banyak dokumen yang cocok dengan kueri kami:
> db.restaurants.find( { cuisine: "Hamburgers" } ).count()
433
Itu banyak sekali burgernya!
Mencari Persamaan Kata Menggunakan Regex
Sekarang kita menggunakan .find()
untuk menanyakan koleksi kami, kami sebenarnya dapat sedikit memodifikasi sintaks kami dan mulai mencari kecocokan berdasarkan kata atau frasa yang mungkin sebagian cocok dalam bidang tertentu, mirip dengan LIKE
operator untuk mesin SQL.
Triknya adalah dengan menggunakan regular expressions
(atau regex
singkatnya), yang pada dasarnya adalah string teks yang mendefinisikan pola pencarian. Ada sejumlah regex
mesin yang ditulis dalam sintaks yang sedikit berbeda, tetapi dasarnya semua pada dasarnya sama, dan dalam hal ini, MongoDB menggunakan Perl Regex (PCRE)
mesin.
Pada tingkat paling dasar, sebuah regex
ekspresi adalah string (rangkaian karakter) yang kedua sisinya diapit oleh satu garis miring (/
).
Misalnya, jika kita ingin menggunakan regex
untuk melakukan kueri yang sama seperti di atas dan mencari tahu berapa banyak restoran yang menyajikan Hamburgers
, kita dapat mengganti string "Hamburgers"
dengan /Hamburgers/
sebagai gantinya:
> db.restaurants.find( { cuisine: /Hamburgers/ } ).count()
433
Pengamat yang jeli mungkin menyadari bahwa kami tidak mengubah apa pun secara efektif tentang kueri aktual yang kami lakukan – kami masih mencari semua dokumen yang berisi cuisine
bidang sama dengan string "Hamburgers"
.
Yang mengatakan, hanya dengan menggunakan regex
alih-alih "string bertanda kutip" normal, kita dapat mulai mencari kecocokan sebagian kata/frasa sebagai gantinya.
Sebagai contoh, mari kita lihat borough
lapangan untuk mendapatkan ide yang lebih baik tentang cara kerjanya. Pertama, kita akan melihat bahwa total ada enam borough dalam koleksi kami:
> db.restaurants.distinct('borough')
[
"Brooklyn",
"Bronx",
"Manhattan",
"Queens",
"Staten Island",
"Missing"
]
Sekarang mari kita gunakan regex
untuk mengetahui jumlah restoran di Bronx
wilayah:
> db.restaurants.find( { borough: /Bronx/ } ).count()
2338
Tapi bayangkan kita ingin mencari jumlah restoran di mana borough
dimulai dengan tiga karakter pertama "Bro"
. Kami akan memodifikasi regex
kami sangat sedikit, seperti:
> db.restaurants.find( { borough: /^Bro/ } ).count()
8424
Kami melihat lebih dari 6000 dokumen tambahan dalam kumpulan hasil ini, yang masuk akal karena kami tidak hanya mendapatkan hasil di mana borough
adalah "Bronx"
, tetapi juga segalanya untuk "Brooklyn"
juga.
Karakter tanda sisipan (^
) menentukan lokasi di string kita yang seharusnya menjadi awal , jadi jika kita memiliki dokumen di mana ketiga huruf itu berada di tengah bidang, kita tidak akan mendapatkan kecocokan.
Sebagai contoh cepat lainnya, mari telusuri di mana saja di bidang untuk karakter "at"
, yang seharusnya memberi kami hasil untuk "Manhattan"
dan "Staten Island"
:
> db.restaurants.find( { borough: /Manhattan/ } ).count()
10259
> db.restaurants.find( { borough: /Staten Island/ } ).count()
969
> db.restaurants.find( { borough: /AT/i } ).count()
11228
Benar saja, kueri terakhir kami telah menggabungkan dua kumpulan hasil menjadi satu.
Anda mungkin memperhatikan bahwa meskipun karakter kami "AT"
adalah huruf besar di regex
our kami string, tetapi mereka huruf kecil dalam catatan dokumen yang sebenarnya, kami masih mengembalikan hasil. Ini karena kami juga menambahkan i
khusus tandai mengikuti garis miring penutup regex kami (/
). Ini menginformasikan regex
mesin yang ingin kita cari menjadi case insensitive
, cocok terlepas dari huruf besar atau kecil.