MongoDB'yi “like” ile nasıl sorgulayabilirim?


1437

SQL sorgusu ile bir şey sorgulamak istiyorum like:

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

Aynı şeyi MongoDB'de nasıl başarabilirim? Ben için bir operatör bulamıyorum likeiçinde belgeler .


7
mongodb'un belgelerine bakın: Gelişmiş Sorgular - Düzenli ifadeler mongodb.org/display/DOCS/…
douyw

7
Sorunuz en az benzer operatör etiketi 5için oy kullanıyor . Eşanlamlı olarak sql-like önermenizi rica edebilir miyim ?
Kermit

3
Bu bağlantı size yardımcı olabilir goo.gl/gdTYK8
Dilip Kr Singh

Yanıtlar:


1945

Bunun olması gerekir:

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

veya benzeri:

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

Bir yerde "m" içeren bir şey arıyorsunuz (SQL ' %' operatörü Regexp ' ' ile eşdeğerdir..* ' ), dizenin başına "m" sabitlenmiş bir şey değil.

Not: mongodb sql "GİBİ" daha güçlü olan düzenli ifadeler kullanır. Düzenli ifadeler ile hayal ettiğiniz herhangi bir desen oluşturabilirsiniz.

Normal ifadeler hakkında daha fazla bilgi için bu bağlantıya bakın https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
regex ile arama pahalı mı?
Freewind

147
Aslında, duruma göre değişir. Sorgu bir dizin kullanmıyorsa ve bir tablo taraması yapmak zorundaysa, kesinlikle pahalı olabilir. 'Şununla başlar' regex sorgusu yapıyorsanız, bu bir dizin kullanabilir. Ne olduğunu görmek için bir açıklama () çalıştırmak en iyisidir.
Kyle Banker

35
Dizenin başlangıcına demirlenmediğinde, biraz pahalıdır. Ama sonra tekrar, LIKESQL'de bir sorgu.
Emily

4
dizenin başlangıcına sabitlendiği sürece sorun değil mi? sonra serin. Bu, ^
user4951

44
Regex i javascript db.users.find({ "name": { $regex: /m/i } })
eklerdim

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

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

Çıkan: paulo, Patric

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

Çıkan: paulo, Patric

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

Çıkan: pedro


güzel örnek! Ben boşluk ile kontrol bitiş buluyorum ve bunu buldum :) / $ /
Phuong

isim için tüm girişleri nasıl buluyorsun? veya SQL'de * için joker karakter? select name from users;Tüm kullanıcıları listeleyen bir şey mi?
anon58192932

1
@ anon58192932 "Kullanıcılar" adlı bir tabloda yalnızca "ad" alanının tüm girdilerini görüntülemek için, 1 istediğiniz alanların değerlerini ayarlayarak project () yöntemini kullanabilirsiniz. project () öğesinde belirtilmeyen alanlar _id dışında getirildi. _id alanı varsayılan olarak yazdırılır; bu, project () yönteminin içine _id için 0 değeri koyarak bastırabilirsiniz. - db.collection.find (). Project ({name: 1, _id: 0}) .toArray (function (err, docs) {console.log (docs); geri arama (dokümanlar);}); Buraya
gauravparmar

282

İçinde

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

yapabilirsin:

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

2
büyük / küçük harfe duyarlı arama için iyi çalışır, lütfen büyük / küçük harfe duyarlı olmayan arama yapmayı nasıl çalıştırabileceğimi söyleyebilir misiniz?
Tahir Yasin

Regex ne olurdu%sometext%
Tahir Yasin

64
@TahirYasin hala merak ediyorsanız, büyük / küçük harfe duyarsız arama şu şekilde yapılır:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

Golang'da mgo gibi kodu kullanarak çözdüm, seçici: = bson.M {"teknisyen": bson.M {"$ regex": tech}}
Sandun Priyanka

1
Bunun kabul edilen cevap olması gerektiğini hissediyorum. Şu anda en basit ve en zarif.
Brett84c

88

PHP'de aşağıdaki kodu kullanabilirsiniz:

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

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

1
RegEx değeriniz kullanıcı girdisinden kaynaklanıyorsa (örn. Bir filtre formu) ve değerin kendisinin RegExp olarak alınmasını istemiyorsanız, buna preg_quote () uygulamanız gerekebilir.
Philipp Rieber

2
Bunu fark ettim, ancak bu aslında yanlış cevap, alt-optimal olmasına rağmen, bunun yerine gerçek BSON regex nesnesini MongoRegex aracılığıyla kullanmalısınız, $ regex $ in gibi bazı komutlarla uyumluluk sorunları var
Sammaye

Bu sözdizimi, değer bir değişkende saklanırsa yararlıdır, bu nedenle sorgu (Ruby'de) olarak yazılabilir:$collection.where(field => {"$regex" => value})
Donny Kurnia

Ama neden dizi değişmezlerini kullanamıyorsunuz?
Alper

53

Mongo'da bunun için normal ifade kullanırsınız.

Örneğin: db.users.find({"name": /^m/})


29
Bence bu sadece "m" ile başlayan isim değerine sahip belgeleri gösteriyor
JackAce

53

Zaten birçok cevap var. Regex ile dize arama için farklı türde gereksinimleri ve çözümleri veriyorum.

Yani kelime içeren regex ile yapabilirsiniz. Ayrıca büyük / $options => iküçük harfe duyarlı olmayan aramalar için de kullanabilirsiniz

İçeren string

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

Değil İçeren mu stringsadece regex ile

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

Tam büyük / küçük harfe duyarlı değil string

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

İle başla string

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

İle bitmek string

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

Bunu bir yer imi ve ihtiyacınız olabilecek diğer değişiklikler için bir referans olarak saklayın .


37

2 seçeneğiniz var:

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

veya

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

İkincisi, büyük / küçük harfe duyarlı olmayanları bulmak için seçeneklerde "i" gibi daha fazla seçeneğiniz vardır. Ve "string" hakkında, örneğin ". String. " (% String%) veya "string. *" (String%) ve ". * String) (% string) gibi kullanabilirsiniz. Normal ifade kullanabilirsiniz istediğin gibi.

Zevk almak!


34

Node.js kullanıyorsanız , bunu yazabileceğinizi söyler:

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

Ayrıca , şunu yazabilirsiniz:

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

Ruby içindeki benzer sözdizimi:collection.where(field => Regexp.new(value))
Donny Kurnia

24

Zaten cevapları aldım ama normal ifadeyi büyük / küçük harf duyarsızlığıyla eşleştirmek için

Aşağıdaki sorguyu kullanabilirsiniz

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

iİçinde /m/ivaka duyarsız belirtir ve .pretty()daha güzel çıktı sağlar


ama burada dinamik olarak değer ayarlamak istersem
KS

@KuldeepKoranga 'm' yerine herhangi bir dinamik değer koyabilirsiniz. istediğin bu mu.
196

var search="feacebook"peki @ The6thSens Evet, nasıl ayarlayabilirim db.users.find ({ "name" : /search/i } )?
KS

@KuldeepKoranga değerini atadınız.
196

1
@KuldeepKoranga stackoverflow.com/questions/7790811/… bu yardımı yapıyor
The6thSense

18

Node.js'deki Mongoose için

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

13

2.6 mongodb'un yeni özelliğini kullanabilirsiniz:

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
AFAIK Mongodb'un metin araması yalnızca varsayılan olarak tüm kelimeler üzerinde çalışır, bu nedenle bu, "Bu metin içeren bir dizedir", ancak "Bu, alt metne sahip bir dizedir" gibi değerlerle eşleşir. Bu yüzden sql'ın "GİBİ" operatörü gibi değil.
rocketmonkey

@Rocketmonkeys true .. "GİBİ operatörü" gibi bir şey için $ regex mongo operatörü kullanabilirsiniz.
46

13

Gelen nodejs proje ve kullanım firavunfaresi kullanımı sorgusu gibi

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);
            });

Benzer sorguyu nasıl kullanabilirim? Bunu denedim ama çalışmıyor:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammed Şahzad

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

Hayatımı kurtardın ahbap. pls biraz $ regex ve $ seçenekleri nedir açıklayabilir misiniz?
Muhammed Şahzad

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'}; }pls neden bu çalışmıyor çalışmıyor bakabilirsiniz?
Muhammed Şahzad

iyi $regex: 'value' arama değer ve düzenli ifade oluşturmak $options: 'i'araçları Case insensitive . Aynı Farklı bir özelliğin değerini ve vazifesi gören kullanılan çünkü kod çalıştı vermedi ve veritabanı koleksiyonu ile yerine getirmek olmamalıdır koşulu.
Shaishab Roy

12

PHP mongo için Like.
Ben php mongo gibi birkaç sorunları vardı. regex params birleştirilmesi bazı durumlarda PHP mongo bulmak alan yardımcı olur bulundu . Daha popüler bir konuya katkıda bulunmak için buraya göndereceğimi düşündüm

Örneğin

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)

Önceki cevaplar ve yorumlara göre $ text (Index) arama, $ regex yöntemine kıyasla kıyaslama ile daha iyi bir çözüm sağlayacaktır. Referans için bu bağlantıyı kontrol edin stackoverflow.com/questions/10610131/… . PHP ve mongoDB ile $ metin endeksi yöntemi uygulamak mümkün mü
sankar muniyappa

12

Şablon değişmezlerini değişkenlerle kullanmak da işe yarar:

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


Bu ex başlamasından searchig - eğer "ad" testlast içeriyorsa ve "son" ile arama yaparsanız sonuç vermeyecektir.
Vikas Chauhan

11

MongoDB Compass ile katı mod sözdizimini kullanmanız gerekir, örneğin:

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

(MongoDB Compass'ta "bunun yerine kullanmanız önemlidir ')



10

SQL'de, ' like ' sorgusu şöyle görünür:

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

MongoDB konsolunda şöyle görünür:

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

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

Ekleme pretty()yöntemi daha okunabilir biçimlendirilmiş JSON yapısı üretmek tüm yerlerde olacaktır.


10

Regex pahalı işlemidir.

Başka bir yol, bir metin dizini oluşturmak ve daha sonra kullanarak arama yapmaktır $search .

Aranabilir olmasını istediğiniz alanların metin dizinini oluşturun:

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

Metin dizininde bir dize arayın:

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

Mükemmel çözüm ... Regex'ler pahalı bir yoldur. 20m belgelerden oluşan bir veri seti ve performans farkı ile çalışmak çok önemlidir (bu bir yetersizliktir)
nivensookharan

1
Gerçekten, bu sadece tüm kelimeler için geçerlidir, bkz. Docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

Go ve mgo sürücüsünde:

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

sonuç, aranan türün yapısal örneğidir


2
pls değişmez alanlarda bson:RegEx{Pattern:"m", Options:"i"}
anahtarlanmamış

8

Aşağıdaki gibi eşleşen normal ifadeler kullanın. 'İ' büyük / küçük harf duyarsızlığını gösterir.

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

Sorgu aşağıdaki gibi olurdu

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

scala ReactiveMongo api için,

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

Görünüşe göre hem javascript /regex_pattern/deseninin hem de mongo {'$regex': 'regex_pattern'}deseninin kullanılmasının nedenleri var . Bkz: MongoBD RegEx Sözdizimi Kısıtlamaları

Bu tam bir RegEx eğitimi değil, ancak yukarıda yüksek oy alan belirsiz bir yazı gördükten sonra bu testleri çalıştırmak için ilham aldım .

> ['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

Spring-Data Mongodb kullanıyorsanız, bunu şu şekilde yapabilirsiniz:

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

4

Mongo kabuğu regex'i desteklediğinden, bu tamamen mümkündür.

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

Sorgunun büyük / küçük harfe duyarsız olmasını istiyorsak, aşağıda gösterildiği gibi "i" seçeneğini kullanabiliriz:

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


4

Toplama alt dize aramasını kullan (indeks ile !!!):

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

Güzel! belgenin tamamını eşleştirmenin bir yolu var mı? veya toplama çerçevesinin bunu yapmak için bir takip sorgusu yapmasını sağlayın? Şu anda bir maç gibi görünüyor:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco

$ proje aşamasında sadece proje ne istiyorsun
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

MYSQL sorgularını MongoDB'ye çevirmek için ücretsiz bir araç buldum. http://www.querymongo.com/ Birkaç sorgu ile kontrol ettim. gördüğüm gibi hemen hemen hepsi doğru. Buna göre, cevap

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

2

MongoRegex kullanımdan kaldırıldı.
MongoDB \ BSON \ Regex Kullan

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

Bunun PHP'deki MongoRegex sınıfına atıfta bulunduğunu belirtmek önemlidir . Düğüm ile ilgili bu soru ile çok ilgili değil. Bu muhtemelen bir yorum veya daha iyisi olmalıdır - ayrı bir gönderide kendi kendine cevaplanan bir soru.
Boaz - Monica'yı

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

Dize kalıplarını ararken, durumdan emin olmadığımız gibi yukarıdaki deseni kullanmak her zaman daha iyidir. Umarım yardımcı olur!!!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.