Wie kann man MongoDB mit "Gefällt mir" abfragen?


1437

Ich möchte etwas mit der SQL- likeAbfrage abfragen:

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

Wie erreiche ich dasselbe in MongoDB? Ich kann likein der Dokumentation keinen Operator finden .


7
Siehe Mongodbs Dokumente: Erweiterte Abfragen - Reguläre Ausdrücke mongodb.org/display/DOCS/…
Douyw

7
Ihre Frage hat mindestens 5Stimmen für das Like-Operator- Tag. Könnte ich Sie bitten , SQL-like als Synonym vorzuschlagen ?
Kermit

3
Dieser Link kann Ihnen helfen, goo.gl/gdTYK8
Dilip Kr Singh

Antworten:


1945

Das müsste sein:

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

o.ä:

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

Sie suchen nach etwas, das irgendwo "m" enthält (der SQL- %Operator "entspricht dem von Regexp .*"), und nicht nach etwas, das "m" am Anfang der Zeichenfolge verankert hat.

Hinweis: Mongodb verwendet reguläre Ausdrücke, die in SQL leistungsfähiger sind als "LIKE". Mit regulären Ausdrücken können Sie jedes Muster erstellen, das Sie sich vorstellen.

Weitere Informationen zu regulären Ausdrücken finden Sie unter diesem Link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
Ist die Suche nach Regex teuer?
Freilauf

147
Eigentlich kommt es darauf an. Wenn die Abfrage keinen Index verwendet und einen Tabellenscan durchführen muss, kann dies sicherlich teuer sein. Wenn Sie eine Regex-Abfrage "Beginnt mit" durchführen, kann dies einen Index verwenden. Führen Sie am besten eine EXPLAIN () aus, um zu sehen, was passiert.
Kyle Banker

35
Wenn es nicht am Anfang der Saite verankert ist, ist es etwas teuer. Aber auch eine LIKEAbfrage in SQL.
Emily

4
Solange es am Anfang der Zeichenfolge verankert ist, ist es in Ordnung? dann cool. bedeutet das, dass wir ^
user4951

44
Ich würde 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%'

raus: paulo, patric

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

raus: paulo, patric

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

raus: pedro


schönes Beispiel! Ich finde Scheck Ende mit Leerzeichen und fand dies :) / $ /
Phuong

Wie finden Sie alle Einträge für den Namen? oder der Platzhalter für * in SQL? Etwas, select name from users;das nur alle Benutzer auflistet?
anon58192932

1
@ anon58192932 Um alle Einträge nur des Felds "name" in einer Tabelle mit dem Namen "users" anzuzeigen, können Sie die project () -Methode verwenden, indem Sie Werte für Felder festlegen, die Sie möchten. 1. Felder, die in project () nicht erwähnt werden, werden nicht angezeigt abgerufen außer _id. Das Feld _id wird standardmäßig gedruckt, das Sie unterdrücken können, indem Sie den Wert 0 für _id in die project () -Methode eingeben. So etwas wie - db.collection.find (). Project ({name: 1, _id: 0}) .toArray (function (err, docs) {console.log (docs); callback (docs);}); Siehe dies - docs.mongodb.com/manual/tutorial/…
gauravparmar

282

Im

  • PyMongo mit Python
  • Mungo mit Node.js.
  • Jongo mit Java
  • mgo mit Go

du kannst tun:

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

2
Es funktioniert gut für die Suche nach Groß- und Kleinschreibung. Können Sie mir bitte sagen, wie ich die Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen kann?
Tahir Yasin

Was wäre die Regex für%sometext%
Tahir Yasin

64
@ TahirYasin, wenn Sie sich immer noch fragen, würde die Suche ohne db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
Berücksichtigung der

Ich löste in Golang mit mgo einfach Code wie folgt, Selektor: = bson.M {"Techniker": bson.M {"$ regex": tech}}
Sandun Priyanka

1
Fühlen Sie sich wie dies sollte die akzeptierte Antwort sein. Es ist derzeit das einfachste und eleganteste.
Brett84c

88

In PHP können Sie folgenden Code verwenden:

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

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

1
Wenn Ihr RegEx-Wert aus Benutzereingaben stammt (z. B. ein Filterformular) und Sie nicht möchten, dass der Wert selbst als RegExp verwendet wird, sollten Sie preg_quote () darauf anwenden.
Philipp Rieber

2
Ich habe das gerade erkannt, aber das ist eigentlich die falsche Antwort, obwohl es funktioniert, ist es nicht optimal. Sie sollten stattdessen das eigentliche BSON-Regex-Objekt über MongoRegex verwenden. $ Regex hat Kompatibilitätsprobleme mit bestimmten Befehlen wie $ in
Sammaye,

Diese Syntax ist nützlich, wenn der Wert in einer Variablen gespeichert ist, so dass die Abfrage wie folgt geschrieben werden kann (in Ruby):$collection.where(field => {"$regex" => value})
Donny Kurnia

Aber warum können Sie keine Array-Literale verwenden?
Alper

53

Sie würden Regex dafür in Mongo verwenden.

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


29
Ich denke, dies zeigt nur Dokumente mit einem Namenswert, der mit "m" beginnt
JackAce

53

Es gibt bereits viele Antworten. Ich gebe verschiedene Arten von Anforderungen und Lösungen für die Zeichenfolgensuche mit Regex.

Sie können mit Regex tun, die Wort enthalten, z. B. wie. Sie können auch $options => ifür die Suche ohne Berücksichtigung der Groß- und Kleinschreibung verwenden

Enthält string

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

Enthält nicht stringnur Regex

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

Genaue Groß- und Kleinschreibung wird nicht berücksichtigt string

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

Beginnen mit string

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

Ende mit string

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

Bewahren Sie dies als Lesezeichen und als Referenz für andere Änderungen auf, die Sie möglicherweise benötigen.


37

Sie haben 2 Möglichkeiten:

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

oder

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

Auf der zweiten haben Sie mehr Optionen, wie "i" in Optionen, um die Groß- und Kleinschreibung nicht zu berücksichtigen. Und für den "String" können Sie beispielsweise ". String. " (% String%) oder "string. *" (String%) und ". * String) (% string) verwenden. Sie können reguläre Ausdrücke verwenden wie du willst.

Genießen!


34

Wenn Sie node.js verwenden , heißt es , dass Sie Folgendes schreiben können:

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

Auch können, schreiben Sie diese:

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

Ähnliche Syntax in Ruby:collection.where(field => Regexp.new(value))
Donny Kurnia

24

Sie haben bereits die Antworten erhalten, aber um Regex mit Groß- und Kleinschreibung zu vergleichen

Sie können die folgende Abfrage verwenden

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

Die iin der /m/izeigt Groß- und Kleinschreibung und .pretty()bietet eine hübsche Ausgabe


aber was ist, wenn ich hier dynamisch Wert setzen möchte
KS

@KuldeepKoranga Sie können einen beliebigen dynamischen Wert anstelle von 'm' platzieren. ist es das was du willst.
The6thSense

var search="feacebook"Wie kann ich unten @ The6thSens einstellen db.users.find ({ "name" : /search/i } )? Ja, aber ?
KS

@ KuldeepKoranga Sie haben den Wert zugewiesen.
The6thSense

1
@ KuldeepKoranga stackoverflow.com/questions/7790811/… hilft dies
The6thSense

18

Für Mungo in Node.js.

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

13

Sie können die neue Funktion von 2.6 mongodb verwenden:

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
Beachten Sie, dass die Textsuche von AFAIK Mongodb standardmäßig nur für ganze Wörter funktioniert. Dies entspricht also Werten wie "Dies ist eine Zeichenfolge mit Text", nicht jedoch "Dies ist eine Zeichenfolge mit Untertext". Es ist also nicht ganz so wie der "LIKE" -Operator von sql.
Rocketmonkeys

@Rocketmonkeys ist wahr .. für so etwas wie "LIKE Operator" würden Sie $ regex Mongo Operator verwenden.
cmarrero01

13

Verwenden Sie in nodejs project and use mongoose die Like-Abfrage

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

Wie kann ich wie Abfrage verwenden? Ich habe dies versucht, aber nicht funktioniert:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammad Shahzad

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

Du rettest mein Leben, Alter. Kannst du bitte wenig erklären, was $ regex und $ options sind?
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'}; }Kannst du bitte schauen, warum das nicht funktioniert?
Muhammad Shahzad

gut $regex: 'value' erzeugen regulären Ausdruck für Ihre Suchwert und $options: 'i'Mittel Groß- und Kleinschreibung . Ihr Code nicht funktioniert hat , weil Sie denselben Wert für andere Eigenschaft verwendet , und diese Handlung als und Bedingung , die nicht mit Ihrer Datenbank Sammlung erfüllen sollte.
Shaishab Roy

12

Für PHP Mongo Like.
Ich hatte mehrere Probleme mit PHP Mongo wie. Ich fand, dass die Verkettung der Regex-Parameter in einigen Situationen hilft, mit denen PHP Mongo Find Field beginnt . Ich dachte, ich würde hier posten, um zu dem populäreren Thread beizutragen

z.B

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)

Gemäß den vorherigen Antworten und Kommentaren bietet die Suche nach $ text (Index) eine bessere Lösung mit einem Benchmark im Vergleich zur richtigen $ regex-Methode. Als Referenz überprüfen Sie diesen Link stackoverflow.com/questions/10610131/… . Ist es möglich, $ Text Index-Methode mit PHP und MongoDB
Sankar Muniyappa

12

Die Verwendung von Vorlagenliteralen mit Variablen funktioniert auch:

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


Dies ist eine Suche ab dem Start von ex - wenn "Vorname" Testlast enthält und wenn ich nach "Last" suche, gibt es kein Ergebnis.
Vikas Chauhan

11

Bei MongoDB Compass müssen Sie die strikte Modus-Syntax als solche verwenden:

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

(In MongoDB Compass ist es wichtig, dass Sie "statt verwenden ')



10

In SQL, das ‚ wie ‘ Abfrage sieht wie folgt aus :

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

In der MongoDB-Konsole sieht es so aus:

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

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

Außerdem wird die pretty()Methode an allen Stellen, an denen eine formatierte JSON-Struktur erzeugt wird, besser lesbar sein.


10

Regex sind teuer sind Prozess.

Eine andere Möglichkeit besteht darin, einen Textindex zu erstellen und ihn dann mit zu durchsuchen $search.

Erstellen Sie einen Textindex mit Feldern, die durchsucht werden sollen:

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

Suchen Sie nach einer Zeichenfolge im Textindex:

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

Perfekte Lösung ... Regex sind viel zu teuer. Die Arbeit mit einem Datensatz von 20 Millionen Dokumenten und der Leistungsunterschied ist sehr, sehr auffällig (was eine Untertreibung ist)
nivensookharan

1
In der Tat funktioniert dies nur für ganze Wörter, siehe docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

In Go und dem mgo-Treiber:

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

Dabei ist result die struct-Instanz des gesuchten Typs


2
Bitte vermeiden Sie nicht verschlüsselte Felder in Literalen, tun Sie bson:RegEx{Pattern:"m", Options:"i"}stattdessen
Bithavoc

8

Verwenden Sie die folgenden regulären Ausdrücke. Das 'i' zeigt die Groß- und Kleinschreibung nicht an.

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

Like Query wäre wie unten gezeigt

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

für 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

Es scheint Gründe zu geben, sowohl das Javascript- /regex_pattern/Muster als auch das Mongo- {'$regex': 'regex_pattern'}Muster zu verwenden. Siehe: MongoBD RegEx-Syntaxbeschränkungen

Dies ist kein vollständiges RegEx-Tutorial, aber ich wurde inspiriert, diese Tests durchzuführen, nachdem ich oben einen mehrstimmigen, mehrdeutigen Beitrag gesehen habe .

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

Wenn Sie Spring-Data Mongodb verwenden, können Sie dies folgendermaßen tun:

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

4

Da Mongo Shell Regex unterstützt, ist dies durchaus möglich.

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

Wenn bei der Abfrage die Groß- und Kleinschreibung nicht berücksichtigt werden soll, können Sie die Option "i" verwenden, wie unten gezeigt:

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


4

Verwenden Sie die Suche nach Aggregationssubstrings (mit Index !!!):

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

nett! Gibt es eine Möglichkeit, das gesamte Dokument abzugleichen? oder das Aggregationsframework dazu veranlassen, eine Folgeabfrage durchzuführen? Im Moment sieht ein Match so aus:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

in $ Projektphase projizieren Sie einfach, was Sie wollen
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

Ich habe ein kostenloses Tool gefunden, um MYSQL-Abfragen in MongoDB zu übersetzen. http://www.querymongo.com/ Ich habe mit mehreren Fragen nachgesehen. Wie ich sehe, sind fast alle richtig. Demnach lautet die Antwort

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

2

MongoRegex ist veraltet.
Verwenden Sie MongoDB \ BSON \ Regex

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

Es ist wichtig zu beachten, dass sich dies auf die MongoRegex-Klasse in PHP bezieht . Nicht sehr relevant für diese Frage, die sich mit Node befasst. Dies sollte wahrscheinlich ein Kommentar oder noch besser sein - eine selbst beantwortete Frage in einem separaten Beitrag.
Boaz - Stellen Sie Monica

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

Wenn wir nach Zeichenfolgenmustern suchen, ist es immer besser, das obige Muster zu verwenden, wenn wir uns über den Fall nicht sicher sind. Ich hoffe, das hilft!!!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.