Contoh:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
mongodb
case-insensitive
Luke Dennis
sumber
sumber
$caseSensitive: false
. Lihat: docs.mongodb.org/manual/reference/operator/query/text/…$caseSensitive
sudah salah secara default, dan itu tidak menjawab pertanyaan, karena hanya berfungsi pada bidang yang diindeks. OP sedang mencari perbandingan string case-insensitive.Jawaban:
Anda bisa menggunakan regex .
Dalam contoh Anda itu akan menjadi:
Namun, saya harus mengatakan, mungkin Anda bisa menurunkan (atau menaikkan) nilai di jalan daripada mengeluarkan biaya tambahan setiap kali Anda menemukannya. Jelas ini tidak akan bekerja untuk nama orang dan semacamnya, tapi mungkin menggunakan case seperti tag.
sumber
MEMPERBARUI:
Jawaban asli sekarang sudah usang. Mongodb sekarang mendukung pencarian teks lengkap tingkat lanjut, dengan banyak fitur.
JAWABAN ASLI:
Perlu dicatat bahwa pencarian dengan case regex tidak peka / i berarti mongodb tidak dapat mencari berdasarkan indeks, sehingga permintaan terhadap dataset besar dapat memakan waktu lama.
Bahkan dengan dataset kecil, itu tidak terlalu efisien. Anda menerima pukulan cpu yang jauh lebih besar daripada waran permintaan Anda, yang bisa menjadi masalah jika Anda mencoba mencapai skala.
Sebagai alternatif, Anda dapat menyimpan salinan huruf besar dan mencarinya. Misalnya, saya memiliki tabel Pengguna yang memiliki nama pengguna yang merupakan case campuran, tetapi id adalah salinan huruf besar dari nama pengguna. Ini memastikan duplikasi case-sensitive tidak mungkin (memiliki "Foo" dan "foo" tidak akan diizinkan), dan saya dapat mencari berdasarkan id = username.toUpperCase () untuk mendapatkan pencarian case-sensitive untuk nama pengguna.
Jika bidang Anda besar, seperti badan pesan, duplikasi data mungkin bukan pilihan yang baik. Saya percaya menggunakan pengindeks luar seperti Apache Lucene adalah pilihan terbaik dalam kasus itu.
sumber
username: 'bill'
mencocokkanBILL
atauBill
, bukan kueri pencarian teks lengkap, yang juga akan cocok dengan kata - kata yang berasal dari kata tangkasbill
, sepertiBills
,billed
dll.Jika Anda perlu membuat regexp dari suatu variabel, ini adalah cara yang lebih baik untuk melakukannya: https://stackoverflow.com/a/10728069/309514
Anda kemudian dapat melakukan sesuatu seperti:
Ini memiliki manfaat menjadi lebih terprogram atau Anda bisa mendapatkan peningkatan kinerja dengan kompilasi sebelumnya jika Anda sering menggunakannya kembali.
sumber
new RegExp("^" + req.params.term.toLowerCase(), "i")
juga berfungsi dengan baikIngatlah bahwa contoh sebelumnya:
akan menyebabkan setiap entri yang berisi bilah cocok dengan kueri (bar1, barxyz, openbar), bisa sangat berbahaya bagi pencarian nama pengguna pada fungsi auth ...
Anda mungkin perlu membuatnya hanya cocok dengan istilah pencarian dengan menggunakan sintaksis regexp yang sesuai seperti:
Lihat http://www.regular-expressions.info/ untuk bantuan sintaks pada ekspresi reguler
sumber
Dimulai dengan MongoDB 3.4, cara yang disarankan untuk melakukan pencarian case-insensitive cepat adalah menggunakan Case Insensitive Index .
Saya secara pribadi mengirim email kepada salah satu pendiri untuk membuatnya bekerja, dan dia mewujudkannya! Itu adalah masalah pada JIRA sejak 2009 , dan banyak yang meminta fitur tersebut. Begini cara kerjanya:
Indeks case-insensitive dibuat dengan menentukan collation dengan kekuatan 1 atau 2. Anda dapat membuat indeks case-insensitive seperti ini:
Anda juga dapat menentukan susunan default per koleksi saat Anda membuatnya:
Dalam kedua kasus tersebut, untuk menggunakan indeks case-insensitive, Anda perlu menentukan susunan yang sama dalam
find
operasi yang digunakan saat membuat indeks atau koleksi:Ini akan mengembalikan "New York", "new york", "New york" dll.
Catatan lain
Jawaban yang menyarankan untuk menggunakan pencarian teks lengkap salah dalam hal ini (dan berpotensi berbahaya ). Pertanyaannya adalah tentang membuat kueri yang tidak peka huruf besar-kecil, misalnya
username: 'bill'
mencocokkanBILL
atauBill
, bukan kueri penelusuran teks lengkap, yang juga akan cocok dengan kata-kata yang berasal daribill
, sepertiBills
,billed
dll.Jawaban yang menyarankan untuk menggunakan ekspresi reguler lambat, karena bahkan dengan indeks, dokumentasi menyatakan :
$regex
jawaban juga menjalankan risiko injeksi input pengguna .sumber
sumber
TL; DR
Cara yang benar untuk melakukan ini di mongo
Jangan Gunakan RegExp
Alami dan gunakan pengindeksan inbuilt mongodb, cari
Langkah 1 :
Langkah 2 :
Perlu membuat indeks pada bidang TEKS mana pun yang ingin Anda cari, tanpa kueri pengindeksan akan sangat lambat
langkah 3:
sumber
username: 'bill'
mencocokkanBILL
atauBill
, bukan kueri pencarian teks lengkap, yang juga akan cocok dengan kata - kata yang berasal dari kata tangkasbill
, sepertiBills
,billed
dll.sumber
$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);
Mongo (versi saat ini 2.0.0) tidak mengizinkan pencarian case-sensitive terhadap bidang yang diindeks - lihat dokumentasi mereka . Untuk bidang yang tidak diindeks, regex yang terdaftar di jawaban lain harus baik-baik saja.
sumber
Satu hal yang sangat penting untuk diingat ketika menggunakan kueri berbasis Regex - Ketika Anda melakukan ini untuk sistem login, lepaskan setiap karakter tunggal yang Anda cari, dan jangan lupa ^ dan $ operator. Lodash memiliki fungsi yang bagus untuk ini , jika Anda sudah menggunakannya:
Mengapa? Bayangkan seorang pengguna memasukkan
.*
nama pengguna. Itu akan cocok dengan semua nama pengguna, memungkinkan login dengan hanya menebak kata sandi pengguna mana pun.sumber
Metode terbaik adalah dalam bahasa pilihan Anda, saat membuat pembungkus model untuk objek Anda, minta metode save () Anda beralih melalui seperangkat bidang yang akan Anda cari yang juga diindeks; kumpulan bidang tersebut harus memiliki mitra huruf kecil yang kemudian digunakan untuk pencarian.
Setiap kali objek disimpan lagi, properti huruf kecil kemudian diperiksa dan diperbarui dengan perubahan apa pun pada properti utama. Ini akan membuatnya sehingga Anda dapat mencari secara efisien, tetapi menyembunyikan pekerjaan tambahan yang diperlukan untuk memperbarui bidang lc setiap kali.
Bidang huruf kecil bisa menjadi kunci: menyimpan objek nilai atau hanya nama bidang dengan awalan lc_. Saya menggunakan yang kedua untuk menyederhanakan kueri (kueri objek dalam bisa membingungkan di kali)
Catatan: Anda ingin mengindeks bidang lc_, bukan bidang utama yang menjadi dasarnya.
sumber
Misalkan Anda ingin mencari "kolom" di "Tabel" dan Anda ingin pencarian tidak case-case. Cara terbaik dan efisien adalah seperti di bawah ini;
Kode di atas hanya menambahkan nilai pencarian Anda sebagai RegEx dan mencari dengan kriteria tidak sensitif yang ditetapkan dengan "i" sebagai opsi.
Semua yang terbaik.
sumber
Menggunakan luwak ini bekerja untuk saya:
sumber
.toLowerCase()
berlebihan jika Anda menetapkan tanda case-insensitive flag ofi
?Kerangka agregasi diperkenalkan di mongodb 2.2. Anda dapat menggunakan operator string "$ strcasecmp" untuk membuat perbandingan case-insensitive antara string. Ini lebih direkomendasikan dan lebih mudah daripada menggunakan regex.
Berikut dokumen resmi pada operator perintah agregasi: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .
sumber
Anda dapat menggunakan Indeks Tidak Sensitif Kasus :
Contoh berikut membuat koleksi tanpa susunan default, lalu menambahkan indeks pada bidang nama dengan susunan case sensitif. Komponen Internasional untuk Unicode
Untuk menggunakan indeks, kueri harus menentukan susunan yang sama.
atau Anda dapat membuat koleksi dengan susunan standar:
sumber
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
Untuk mencari variabel dan menghindarinya:
Melarikan diri dari variabel melindungi permintaan terhadap serangan dengan '. *' Atau regex lainnya.
escape-string-regexp
sumber
Gunakan RegExp , Jika ada opsi lain yang tidak bekerja untuk Anda, RegExp adalah pilihan yang baik. Itu membuat case string tidak sensitif.
gunakan nama pengguna dalam kueri, dan kemudian selesai.
Saya harap ini juga akan berhasil untuk Anda. Semua yang terbaik.
sumber
Saya telah membuat Func sederhana untuk case regex tidak sensitif, yang saya gunakan dalam filter saya.
Maka Anda cukup memfilter pada bidang sebagai berikut.
sumber
Menggunakan filter berfungsi untuk saya dalam C #.
Bahkan mungkin menggunakan indeks karena saya percaya metode dipanggil setelah pengembalian terjadi tetapi saya belum menguji ini.
Ini juga menghindari masalah
bahwa mongodb akan menganggap p.Title.ToLower () adalah properti dan tidak akan dipetakan dengan benar.
sumber
Untuk siapa pun yang menggunakan Golang dan ingin memiliki pencarian teks lengkap yang peka huruf dengan mongodb dan perpustakaan mgo godoc globalsign .
sumber
Seperti yang dapat Anda lihat di mongo docs - karena
$text
indeks versi 3.2 tidak peka huruf besar-kecil: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivityBuat indeks teks dan gunakan $ text operator dalam permintaan Anda .
sumber
username: 'bill'
mencocokkanBILL
atauBill
, bukan kueri pencarian teks lengkap, yang juga akan cocok dengan kata - kata yang berasal dari kata tangkasbill
, sepertiBills
,billed
dll.Ini telah diuji untuk pencarian string
sumber
Saya telah menghadapi masalah yang sama dan inilah yang bekerja untuk saya:
sumber
$regex
dan$options
. Apa yang Anda Ctrl + F?$regex
tidak efisien dan berpotensi tidak aman, seperti yang saya jelaskan di edit saya untuk jawaban 2016 lainnya ini . Tidak ada salahnya menghapus jawaban jika mereka tidak lagi melayani komunitas!