Bagaimana cara menanyakan MongoDB dengan "suka"?


1437

Saya ingin menanyakan sesuatu dengan likepermintaan SQL :

SELECT * FROM users  WHERE name LIKE '%m%'

Bagaimana cara saya mencapai hal yang sama di MongoDB? Saya tidak dapat menemukan operator likedalam dokumentasi .


7
lihat dokumen mongodb: Kueri Tingkat Lanjut - Ekspresi reguler mongodb.org/display/DOCS/…
douyw

7
Pertanyaan Anda setidaknya memiliki 5suara untuk tag seperti operator . Bisakah saya meminta agar Anda menyarankan seperti sql sebagai sinonim ?
Kermit

3
Tautan ini dapat membantu Anda goo.gl/gdTYK8
Dilip Kr Singh

Jawaban:


1945

Itu pasti:

db.users.find({"name": /.*m.*/})

atau, serupa:

db.users.find({"name": /m/})

Anda sedang mencari sesuatu yang mengandung "m" di suatu tempat ( %operator SQL ' setara dengan Regexp' .*'), bukan sesuatu yang memiliki "m" berlabuh ke awal string.

catatan: mongodb menggunakan ekspresi reguler yang lebih kuat daripada "LIKE" dalam sql. Dengan ekspresi reguler, Anda dapat membuat pola apa pun yang Anda bayangkan.

Untuk info lebih lanjut tentang ekspresi reguler, lihat tautan ini https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
Apakah pencarian dengan regex mahal?
Freewind

147
Sebenarnya itu tergantung. Jika kueri tidak menggunakan indeks, dan harus melakukan pemindaian tabel, maka pastinya bisa mahal. Jika Anda melakukan permintaan regex 'dimulai dengan', maka itu bisa menggunakan indeks. Terbaik untuk menjalankan penjelasan () untuk melihat apa yang terjadi.
Kyle Banker

35
Ketika tidak berlabuh ke awal string, itu agak mahal. Tapi sekali lagi, begitu pula LIKEpermintaan dalam SQL.
Emily

4
jadi selama itu berlabuh ke awal string tidak apa-apa? keren kalau begitu. apakah itu berarti kita perlu menambahkan ^
user4951

44
Saya akan menambahkan regex ijavascript db.users.find({ "name": { $regex: /m/i } })
Doron Segal

368
db.users.insert({name: 'paulo'})
db.users.insert({name: 'patric'})
db.users.insert({name: 'pedro'})

db.users.find({name: /a/})  //like '%a%'

keluar: paulo, patric

db.users.find({name: /^pa/}) //like 'pa%' 

keluar: paulo, patric

db.users.find({name: /ro$/}) //like '%ro'

keluar: pedro


contoh yang bagus! Saya menemukan ujung cek dengan ruang dan menemukan ini :) / $ /
Phuong

bagaimana Anda menemukan semua entri untuk nama? atau wildcard untuk * dalam SQL? Sesuatu yang tidak select name from users;hanya mencantumkan semua pengguna?
anon58192932

1
@ anon58192932 Untuk menampilkan semua entri hanya bidang "nama" dalam tabel bernama "pengguna", Anda dapat menggunakan metode project () dengan menetapkan nilai bidang yang ingin Anda 1. Bidang yang tidak disebutkan dalam proyek () tidak akan diambil kecuali _id. Bidang _id dicetak secara default yang dapat Anda tekan dengan meletakkan nilai 0 untuk metode _id di dalam project (). Sesuatu seperti - db.collection.find (). Project ({name: 1, _id: 0}) .toArray (fungsi (err, docs) {console.log (docs); callback (docs);}); Merujuk ini - docs.mongodb.com/manual/tutorial/...
gauravparmar

282

Di

  • PyMongo menggunakan Python
  • Mongoose menggunakan Node.js
  • Jongo , menggunakan Java
  • mgo , menggunakan Go

Anda dapat melakukan:

db.users.find({'name': {'$regex': 'sometext'}})

2
berfungsi baik untuk pencarian case sensitif, bisakah Anda memberi tahu saya bagaimana saya bisa membuatnya bekerja untuk melakukan pencarian case sensitif?
Tahir Yasin

Apa yang akan menjadi regex untuk%sometext%
Tahir Yasin

64
@TahirYasin jika Anda masih bertanya-tanya, pencarian case-insensitive akan dilakukan seperti ini:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

Saya menyelesaikannya di golang menggunakan kode sederhana mgo seperti ini, pemilih: = bson.M {"teknisi": bson.M {"$ regex": tech}}
Sandun Priyanka

1
Merasa seperti ini harus menjadi jawaban yang diterima. Ini yang paling sederhana dan paling elegan saat ini.
Brett84c

88

Di PHP, Anda dapat menggunakan kode berikut:

$collection->find(array('name'=> array('$regex' => 'm'));

4
python + mongoengine: people = People.objects.raw_query ({'name': {'$ regex': 'm'}})
panchicore

1
Jika nilai RegEx Anda berasal dari input pengguna (mis. Formulir filter) dan Anda tidak ingin nilai itu sendiri diambil sebagai RegExp, Anda harus menerapkan preg_quote () untuknya.
Philipp Rieber

2
Saya baru menyadari ini, tetapi ini sebenarnya jawaban yang salah, meskipun itu berfungsi kurang optimal, Anda sebaiknya menggunakan objek regon BSON aktual melalui MongoRegex, $ regex memiliki masalah kompatibilitas dengan perintah tertentu seperti $ in
Sammaye

Sintaks ini berguna jika nilainya disimpan dalam variabel, sehingga kueri dapat ditulis sebagai (dalam Ruby):$collection.where(field => {"$regex" => value})
Donny Kurnia

Tetapi mengapa Anda tidak bisa menggunakan literal array?
Alper

53

Anda akan menggunakan regex untuk itu di mongo.

misalnya: db.users.find({"name": /^m/})


29
Saya pikir ini hanya menunjukkan dokumen dengan nilai nama yang dimulai dengan "m"
JackAce

53

Sudah ada banyak jawaban. Saya memberikan berbagai jenis persyaratan dan solusi untuk pencarian string dengan regex.

Anda dapat melakukannya dengan regex yang berisi kata seperti like. Anda juga dapat menggunakan $options => iuntuk pencarian case-sensitive

Mengandung string

db.collection.find({name:{'$regex' : 'string', '$options' : 'i'}})

Tidak Berisi stringhanya dengan regex

db.collection.find({name:{'$regex' : '^((?!string).)*$', '$options' : 'i'}})

Tidak sensitif case persis string

db.collection.find({name:{'$regex' : '^string$', '$options' : 'i'}})

Dimulai dari string

db.collection.find({name:{'$regex' : '^string', '$options' : 'i'}})

Berakhir dengan string

db.collection.find({name:{'$regex' : 'string$', '$options' : 'i'}})

Simpan ini sebagai bookmark, dan referensi untuk perubahan lain yang mungkin Anda butuhkan.


37

Anda memiliki 2 pilihan:

db.users.find({"name": /string/})

atau

db.users.find({"name": {"$regex": "string", "$options": "i"}})

Yang kedua Anda memiliki lebih banyak opsi, seperti "i" dalam opsi untuk menemukan penggunaan case-insensitive. Dan tentang "string", Anda dapat menggunakan seperti ". String. " (% String%), atau "string. *" (String%) dan ". * String) (% string) misalnya. Anda dapat menggunakan ekspresi reguler seperti yang kamu inginkan.

Nikmati!


34

Jika menggunakan node.js , itu mengatakan bahwa Anda dapat menulis ini:

db.collection.find( { field: /acme.*corp/i } );
//or
db.collection.find( { field: { $regex: 'acme.*corp', $options: 'i' } } );

Juga , Anda dapat menulis ini:

db.collection.find( { field: new RegExp('acme.*corp', 'i') } );

Sintaks serupa di Ruby:collection.where(field => Regexp.new(value))
Donny Kurnia

24

Sudah Anda mendapatkan jawaban tetapi untuk mencocokkan regex dengan ketidakpekaan huruf

Anda bisa menggunakan kueri berikut

db.users.find ({ "name" : /m/i } ).pretty()

The idalam /m/imenunjukkan kasus ketidakpekaan dan .pretty()memberikan output lebih cantik


tetapi bagaimana jika saya ingin menetapkan nilai secara dinamis di sini
KS

@KuldeepKoranga Anda dapat menempatkan nilai dinamis apa pun di tempat 'm'. itu yang kamu inginkan.
The6thSense

var search="feacebook"jadi bagaimana saya bisa mengatur di bawah @ The6thSens Ya, tapi db.users.find ({ "name" : /search/i } )?
KS

@KuldeepKoranga Anda telah menetapkan nilainya.
The6thSense

1
@KuldeepKoranga stackoverflow.com/questions/7790811/… melakukan ini membantu
The6thSense

18

Untuk luwak di Node.js

db.users.find({'name': {'$regex': '.*sometext.*'}})

13

Anda dapat menggunakan fitur baru 2,6 mongodb:

db.foo.insert({desc: "This is a string with text"});
db.foo.insert({desc:"This is a another string with Text"});
db.foo.ensureIndex({"desc":"text"});
db.foo.find({
    $text:{
        $search:"text"
    }
});

6
Catatan, pencarian teks AFAIK Mongodb hanya berfungsi pada seluruh kata secara default, jadi ini akan cocok dengan nilai-nilai seperti "Ini adalah string dengan teks", tetapi tidak "Ini adalah string dengan subteks". Jadi tidak seperti operator "LIKE" sql.
rocketmonkeys

@Rocketmonkeys itu benar .. untuk sesuatu seperti "LIKE operator", Anda akan menggunakan $ regex mongo operator.
cmarrero01

13

Dalam proyek nodejs dan gunakan luong gunakan Seperti permintaan

var User = mongoose.model('User');

var searchQuery={};
searchQuery.email = req.query.email;
searchQuery.name = {$regex: req.query.name, $options: 'i'};
User.find(searchQuery, function(error, user) {
                if(error || user === null) {
                    return res.status(500).send(error);
                }
                return res.status(200).send(user);
            });

Bagaimana saya bisa menggunakan permintaan seperti? Saya telah mencoba ini tetapi tidak berhasil:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammad Shahzad

dapat mencoba seperti:searchQuery.product_name= {$regex: req.query.search.value, $options: 'i'};
Shaishab Roy

Anda menyelamatkan hidup saya Bung. dapatkah Anda menjelaskan sedikit apa itu $ regex dan $ options?
Muhammad Shahzad

if(req.query.search.value){ searchQuery.product_name = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_amount = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_person = {$regex: req.query.search.value, $options: 'i'}; searchQuery.department_name = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_date = {$regex: req.query.search.value, $options: 'i'}; }dapatkah Anda melihat mengapa ini tidak berhasil?
Muhammad Shahzad

juga $regex: 'value' menghasilkan ekspresi reguler untuk nilai pencarian dan Anda $options: 'i'berarti kasus sensitif . Kode Anda tidak berfungsi karena Anda menggunakan nilai yang sama untuk properti yang berbeda dan itu bertindak sebagai dan kondisi yang tidak boleh dipenuhi dengan koleksi database Anda.
Shaishab Roy

12

Untuk PHP mongo Like.
Saya punya beberapa masalah dengan php seperti mongo. Saya menemukan bahwa menggabungkan params regex membantu dalam beberapa situasi PHP mongo menemukan bidang dimulai dengan . Saya pikir saya akan memposting di sini untuk berkontribusi pada utas yang lebih populer

misalnya

db()->users->insert(['name' => 'john']);
db()->users->insert(['name' => 'joe']);
db()->users->insert(['name' => 'jason']);

// starts with
$like_var = 'jo';
$prefix = '/^';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);
output: (joe, john)

// contains
$like_var = 'j';
$prefix = '/';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);

output: (joe, john, jason)

Sesuai jawaban dan komentar sebelumnya, pencarian $ text (Index) akan memberikan solusi yang lebih baik dengan tolok ukur membandingkan dengan metode $ regex benar. Untuk referensi, periksa tautan ini stackoverflow.com/questions/10610131/… . Apakah mungkin untuk menerapkan metode $ text index dengan PHP dan
mongoDB

12

Menggunakan templat literal dengan variabel juga berfungsi:

{"firstname": {$regex : `^${req.body.firstname}.*` , $options: 'si' }}


Ini adalah searchig dari mulai ex - jika "firstname" mengandung testlast dan jika saya mencari dengan "last" tidak akan memberikan hasil.
Vikas Chauhan

11

Dengan Kompas MongoDB, Anda perlu menggunakan sintaks mode ketat, seperti:

{ "text": { "$regex": "^Foo.*", "$options": "i" } }

(Dalam Kompas MongoDB, penting bahwa Anda menggunakan "bukan ')



10

Dalam SQL, kueri ' seperti ' terlihat seperti ini:

select * from users where name like '%m%'

Di konsol MongoDB, tampilannya seperti ini:

db.users.find({"name": /m/})     // Not JSON formatted

db.users.find({"name": /m/}).pretty()  // JSON formatted

Selain itu pretty()metode akan di semua tempat di mana menghasilkan struktur JSON diformat yang lebih mudah dibaca.


10

Regex adalah proses yang mahal.

Cara lain adalah dengan membuat indeks teks dan kemudian mencarinya menggunakan $search.

Buat Indeks teks bidang yang ingin Anda cari:

db.collection.createIndex({name: 'text', otherField: 'text'});

Cari string dalam indeks teks:

db.collection.find({
  '$text'=>{'$search': "The string"}
})

Solusi sempurna ... Regex adalah cara yang mahal. Bekerja dengan kumpulan data dokumen 20m dan perbedaan kinerja sangat sangat nyata (yang meremehkan)
nivensookharan

1
Memang, ini hanya berfungsi untuk seluruh kata, lihat docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

In Go dan driver mgo:

Collection.Find(bson.M{"name": bson.RegEx{"m", ""}}).All(&result)

di mana hasilnya adalah contoh struct dari tipe yang dicari


2
tolong hindari bidang yang tidak bson:RegEx{Pattern:"m", Options:"i"}
dikunci

8

Gunakan persamaan reguler yang cocok seperti di bawah ini. Huruf 'i' menunjukkan ketidakpekaan huruf besar-kecil.

var collections = mongoDatabase.GetCollection("Abcd");

var queryA = Query.And(
         Query.Matches("strName", new BsonRegularExpression("ABCD", "i")), 
         Query.Matches("strVal", new BsonRegularExpression("4121", "i")));

var queryB = Query.Or(
       Query.Matches("strName", new BsonRegularExpression("ABCD","i")),
       Query.Matches("strVal", new BsonRegularExpression("33156", "i")));

var getA = collections.Find(queryA);
var getB = collections.Find(queryB);

6

Seperti Query akan seperti yang ditunjukkan di bawah ini

db.movies.find({title: /.*Twelve Monkeys.*/}).sort({regularizedCorRelation : 1}).limit(10);

untuk scala ReactiveMongo api,

val query = BSONDocument("title" -> BSONRegex(".*"+name+".*", "")) //like
val sortQ = BSONDocument("regularizedCorRelation" -> BSONInteger(1))
val cursor = collection.find(query).sort(sortQ).options(QueryOpts().batchSize(10)).cursor[BSONDocument]

6

Tampaknya ada alasan untuk menggunakan /regex_pattern/pola javascript maupun {'$regex': 'regex_pattern'}pola mongo . Lihat: Pembatasan Syntax MongoBD RegEx

Ini bukan tutorial RegEx yang lengkap, tetapi saya terinspirasi untuk menjalankan tes ini setelah melihat posting ambigu yang sangat terpilih di atas .

> ['abbbb','bbabb','bbbba'].forEach(function(v){db.test_collection.insert({val: v})})

> db.test_collection.find({val: /a/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }

> db.test_collection.find({val: /.*a.*/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }

> db.test_collection.find({val: /.+a.+/})
{ "val" : "bbabb" }

> db.test_collection.find({val: /^a/})
{ "val" : "abbbb" }

> db.test_collection.find({val: /a$/})
{ "val" : "bbbba" }

> db.test_collection.find({val: {'$regex': 'a$'}})
{ "val" : "bbbba" }

5

Jika Anda menggunakan Spring-Data Mongodb Anda bisa melakukan ini dengan cara ini:

String tagName = "m";
Query query = new Query();
query.limit(10);        
query.addCriteria(Criteria.where("tagName").regex(tagName));

4

Sebagai Mongo shell mendukung regex, itu sangat mungkin.

db.users.findOne({"name" : /.*sometext.*/});

Jika kami ingin kueri tidak peka huruf besar-kecil, kami dapat menggunakan opsi "i", seperti yang ditunjukkan di bawah ini:

db.users.findOne({"name" : /.*sometext.*/i});


4

Gunakan pencarian substring agregasi (dengan indeks !!!):

db.collection.aggregate([{
        $project : {
            fieldExists : {
                $indexOfBytes : ['$field', 'string']
            }
        }
    }, {
        $match : {
            fieldExists : {
                $gt : -1
            }
        }
    }, {
        $limit : 5
    }
]);

bagus! apakah ada cara agar seluruh dokumen cocok? atau membuat kerangka agregasi membuat kueri tindak lanjut untuk melakukan itu? Saat ini sebuah pertandingan terlihat seperti:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

dalam $ tahap proyek hanya proyek apa yang Anda inginkan
Vokail

4

String deepakparmar, dipak, parmar

db.getCollection('yourdb').find({"name":/^dee/})

ans deepakparmar

db.getCollection('yourdb').find({"name":/d/})

ans deepakparmar, dipak

db.getCollection('yourdb').find({"name":/mar$/})

ans deepakparmar, parmar


2

Saya menemukan alat gratis untuk menerjemahkan pertanyaan MYSQL ke MongoDB. http://www.querymongo.com/ Saya memeriksa beberapa pertanyaan. seperti yang saya lihat hampir semuanya benar. Menurut itu, jawabannya adalah

db.users.find({
    "name": "%m%"
});

2

MongoRegex telah ditinggalkan.
Gunakan MongoDB \ BSON \ Regex

$regex = new MongoDB\BSON\Regex ( '^m');
$cursor = $collection->find(array('users' => $regex));
//iterate through the cursor

Penting untuk dicatat bahwa ini merujuk ke kelas MongoRegex di PHP . Tidak terlalu relevan dengan pertanyaan ini yaitu tentang Node. Ini mungkin harus komentar atau lebih baik lagi - pertanyaan yang dijawab sendiri di pos terpisah.
Boaz - Reinstate Monica

2
db.customer.find({"customerid": {"$regex": "CU_00000*", "$options": "i"}}).pretty()

Saat kami mencari pola string, selalu lebih baik menggunakan pola di atas karena ketika kami tidak yakin dengan huruf besar-kecil. Semoga itu bisa membantu !!!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.