Come interrogare MongoDB con "mi piace"?


1437

Voglio interrogare qualcosa con la likequery di SQL :

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

Come posso ottenere lo stesso in MongoDB? Non riesco a trovare un operatore likenella documentazione .


7
vedere i documenti di mongodb: query avanzate - espressioni regolari mongodb.org/display/DOCS/…
douyw

7
La tua domanda ha almeno 5voti per il tag like-operator . Potrei richiedere gentilmente di suggerire sql-like come sinonimo ?
Kermit

3
Questo link può aiutarti a goo.gl/gdTYK8
Dilip Kr Singh

Risposte:


1945

Dovrebbe essere:

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

o simili:

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

Stai cercando qualcosa che contenga "m" da qualche parte (l' %operatore " SQL" equivale a Regexp's " .*"), non qualcosa che abbia "m" ancorato all'inizio della stringa.

nota: mongodb usa espressioni regolari che sono più potenti di "MI PIACE" in sql. Con le espressioni regolari puoi creare qualsiasi modello che immagini.

Per ulteriori informazioni sulle espressioni regolari, fare riferimento a questo link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
la ricerca di regex è costosa?
Freewind,

147
In realtà dipende. Se la query non utilizza un indice e deve eseguire una scansione della tabella, può sicuramente essere costosa. Se stai eseguendo una query regex "inizia con", puoi utilizzare un indice. Meglio eseguire un spiegazione () per vedere cosa sta succedendo.
Kyle Banker,

35
Quando non è ancorato all'inizio della stringa, è piuttosto costoso. Ma poi di nuovo, così è una LIKEquery in SQL.
Emily,

4
quindi finché è ancorato all'inizio della stringa va bene? bene allora. significa che dobbiamo aggiungere ^
user4951

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

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

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

fuori: paulo, patric

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

fuori: paulo, patric

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

fuori: pedro


bell'esempio! Sto trovando il check check con spazio e ho trovato questo :) / $ /
Phuong

come trovi tutte le voci per nome? o il carattere jolly per * in SQL? Qualcosa che fa select name from users;che elenca solo tutti gli utenti?
anon58192932

1
@ anon58192932 Per visualizzare tutte le voci del solo campo "nome" in una tabella denominata "utenti", è possibile utilizzare il metodo project () impostando i valori dei campi che si desidera 1. I campi che non sono menzionati in project () non saranno recuperato tranne _id. Il campo _id viene stampato per impostazione predefinita che è possibile eliminare inserendo il valore 0 per il metodo _id all'interno del progetto (). Qualcosa di simile a - db.collection.find (). Project ({name: 1, _id: 0}) .toArray (function (err, docs) {console.log (docs); callback (docs);}); Riferiscilo - docs.mongodb.com/manual/tutorial/…
gauravparmar

282

In

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

tu puoi fare:

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

2
funziona bene per la ricerca con distinzione tra maiuscole e minuscole, potresti dirmi come posso farlo per eseguire una ricerca senza distinzione tra maiuscole e minuscole?
Tahir Yasin,

Quale sarebbe la regex per%sometext%
Tahir Yasin

64
@TahirYasin se ti stai ancora chiedendo, la ricerca senza distinzione tra maiuscole e minuscole verrebbe eseguita in questo modo:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

Ho risolto il golang usando mgo semplicemente codice come questo, selettore: = bson.M {"tecnico": bson.M {"$ regex": tech}}
Sandun Priyanka

1
Senti che questa dovrebbe essere la risposta accettata. Attualmente è il più semplice ed elegante.
Brett84c,

88

In PHP, puoi usare il seguente codice:

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

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

1
Se il valore RegEx proviene dall'input dell'utente (ad esempio un modulo filtro) e non si desidera che il valore stesso venga assunto come RegExp, è possibile applicare preg_quote () ad esso.
Philipp Rieber,

2
Ho appena capito questo, ma questa è in realtà la risposta sbagliata, anche se funziona non è ottimale, dovresti invece usare l'oggetto regex BSON reale tramite MongoRegex, $ regex ha problemi di compatibilità con alcuni comandi come $ in
Sammaye

Questa sintassi è utile se il valore è archiviato in una variabile, quindi la query potrebbe essere scritta come (in Ruby):$collection.where(field => {"$regex" => value})
Donny Kurnia,

Ma perché non puoi usare i letterali array?
Alper,

53

Userai regex per questo in mongo.

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


29
Penso che questo mostri solo i documenti con un valore del nome che inizia con "m"
JackAce,

53

Ci sono già molte risposte. Sto offrendo diversi tipi di requisiti e soluzioni per la ricerca di stringhe con regex.

Puoi fare con regex che contiene la parola cioè come. Inoltre è possibile utilizzare $options => iper la ricerca senza distinzione tra maiuscole e minuscole

contiene string

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

Non contiene stringsolo con regex

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

Maiuscole e minuscole esatte string

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

Iniziare con string

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

Termina con string

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

Mantenere questo come segnalibro, e un punto di riferimento per tutte le altre modifiche potrebbe essere necessario.


37

Hai 2 scelte:

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

o

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

Nella seconda hai più opzioni, come "i" nelle opzioni per trovare usando la distinzione tra maiuscole e minuscole. E riguardo alla "stringa", puoi usare come ". String. " (% String%), o "string. *" (String%) e ". * String) (% string) per esempio. Puoi usare espressioni regolari come vuoi.

Godere!


34

Se si utilizza node.js , si dice che è possibile scrivere questo:

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

Inoltre , puoi scrivere questo:

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

Sintassi simile in Ruby:collection.where(field => Regexp.new(value))
Donny Kurnia,

24

Hai già ottenuto le risposte, ma per abbinare regex all'insensibilità al caso

È possibile utilizzare la seguente query

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

La iin /m/iindica insensibilità al maiuscolo / minuscolo e .pretty()fornisce un risultato più grazioso


ma cosa succede se voglio impostare il valore in modo dinamico qui
KS

@KuldeepKoranga potresti posizionare qualsiasi valore dinamico al posto di 'm'. È questo che vuoi.
The6thSense

var search="feacebook"quindi come posso impostare sotto @ The6thSens Sì, ma db.users.find ({ "name" : /search/i } )?
KS,

@KuldeepKoranga hai assegnato il valore.
The6thSense

1
@KuldeepKoranga stackoverflow.com/questions/7790811/... fa questo aiuto
The6thSense

18

Per Mongoose in Node.js

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

13

È possibile utilizzare la nuova funzionalità di 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
Nota, la ricerca di testo di AFAIK Mongodb funziona su parole intere solo per impostazione predefinita, quindi corrisponderà a valori come "Questa è una stringa con testo", ma non "Questa è una stringa con sottotesto". Quindi non è proprio come l'operatore "LIKE" di sql.
rocketmonkeys,

@Rocketmonkeys è vero .. per qualcosa come "LIKE operator" useresti $ regex mongo operator.
cmarrero01

13

Nel progetto nodejs e usa mongoose usa Like query

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

Come posso usare come query? L'ho provato ma non funzionava:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammad Shahzad,

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

Mi hai salvato la vita amico. puoi spiegare poco cos'è $ regex e $ 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'}; }puoi guardare perché questo non funziona?
Muhammad Shahzad,

ben $regex: 'value' generare espressioni regolari per il valore di ricerca e $options: 'i'mezzi case insensitive . Il codice non ha funzionato a causa del fatto che hai utilizzato lo stesso valore per proprietà diverse e che agiscono come e condizioni che non dovrebbero soddisfare con la tua raccolta di database.
Shaishab Roy,

12

Per PHP mongo Like.
Ho avuto diversi problemi con php mongo like. ho scoperto che concatenare i parametri regex aiuta in alcune situazioni che PHP mongo trova il campo inizia con . Ho pensato di postare qui per contribuire al thread più popolare

per esempio

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)

In base alle risposte e ai commenti precedenti, la ricerca $ text (indice) fornirà una soluzione migliore con il benchmark rispetto al metodo $ regex corretto. Per riferimento consultare questo link stackoverflow.com/questions/10610131/… . È possibile implementare il metodo dell'indice $ text con PHP e mongoDB
sankar muniyappa

12

L'uso dei letterali di template con variabili funziona anche:

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


Si tratta di cercare dall'inizio se - "firstname" contiene testlast e se cerco per "last" non darà risultati.
Vikas Chauhan,

11

Con MongoDB Compass, è necessario utilizzare la sintassi della modalità rigorosa, come tale:

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

(Nella bussola MongoDB, è importante utilizzare al "posto di ')



10

In SQL, la query " like " è simile alla seguente:

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

Nella console MongoDB, si presenta così:

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

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

In aggiunta pretty()metodo sarà in tutti i luoghi in cui produce una struttura JSON formattata che è più leggibile.


10

Regex sono costosi sono processo.

Un altro modo è creare un indice di testo e quindi cercarlo utilizzando $search.

Crea un indice di testo dei campi che desideri rendere ricercabile:

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

Cerca una stringa nell'indice di testo:

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

Soluzione perfetta ... I regex sono troppo costosi. Lavorare con un set di dati di 20 milioni di documenti e la differenza di prestazioni è molto evidente (il che è un eufemismo)
nivensookharan,

1
In effetti, questo funziona solo per parole intere, vedi docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

In Go e il driver mgo:

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

dove risultato è l'istanza struct del tipo ricercato


2
per favore evita i campi non chiave nei letterali, fai bson:RegEx{Pattern:"m", Options:"i"}invece
bithavoc il

8

Usa le espressioni regolari corrispondenti come di seguito. La "i" mostra insensibilità al maiuscolo / minuscolo.

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

Come Query sarebbe come mostrato di seguito

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

per 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

Sembra che ci siano ragioni per usare sia il /regex_pattern/modello javascript che il {'$regex': 'regex_pattern'}modello mongo . Vedi: Restrizioni alla sintassi MongoBD RegEx

Questo non è un tutorial completo su RegEx, ma sono stato ispirato a eseguire questi test dopo aver visto un post ambiguo molto votato sopra .

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

Se si utilizza Spring-Data Mongodb È possibile farlo in questo modo:

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

4

Poiché la shell Mongo supporta regex, questo è completamente possibile.

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

Se vogliamo che la query non faccia distinzione tra maiuscole e minuscole, possiamo usare l'opzione "i", come mostrato di seguito:

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


4

Usa la ricerca per sottostringa di aggregazione (con indice !!!):

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

simpatico! c'è un modo per far corrispondere l'intero documento? o fare in modo che il framework di aggregazione faccia una query di follow-up per farlo? Al momento una partita sembra:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

in $ project stage basta proiettare quello che vuoi
Vokail

4

Corda 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

Ho trovato uno strumento gratuito per tradurre le query MYSQL in MongoDB. http://www.querymongo.com/ Ho controllato con diverse domande. come vedo quasi tutti sono corretti. In base a ciò, la risposta è

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

2

MongoRegex è stato deprecato.
Usa MongoDB \ BSON \ Regex

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

È importante notare che questo si riferisce alla classe MongoRegex in PHP . Non molto rilevante per questa domanda che riguarda Nodo. Questo dovrebbe probabilmente essere un commento o meglio ancora - una domanda con risposta autonoma in post separato.
Boaz - Ripristina Monica l'

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

Quando cerchiamo schemi di stringhe, è sempre meglio usare lo schema sopra come quando non siamo sicuri del caso. Spero che aiuti!!!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.