¿Cómo consultar MongoDB con "me gusta"?


1437

Quiero consultar algo con la likeconsulta de SQL :

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

¿Cómo hago para lograr lo mismo en MongoDB? No puedo encontrar un operador likeen la documentación .


77
ver los documentos de mongodb: Consultas avanzadas - Expresiones regulares mongodb.org/display/DOCS/…
douyw

77
Su pregunta tiene al menos 5votos para la etiqueta de operador similar . ¿Podría solicitar amablemente que sugiera sql-like como sinónimo ?
Kermit

3
Este enlace puede ayudarte a goo.gl/gdTYK8
Dilip Kr Singh

Respuestas:


1945

Eso tendría que ser:

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

o similar:

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

Está buscando algo que contenga "m" en alguna parte (el %operador ' ' de SQL es equivalente a ' .*' de Regexp ), no algo que tenga "m" anclado al comienzo de la cadena.

nota: mongodb usa expresiones regulares que son más poderosas que "LIKE" en sql. Con expresiones regulares puedes crear cualquier patrón que imagines.

Para obtener más información sobre expresiones regulares, consulte este enlace https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
¿Es caro buscar por expresiones regulares?
Freewind

147
En realidad, depende. Si la consulta no usa un índice y debe hacer un escaneo de tabla, entonces ciertamente puede ser costoso. Si está haciendo una consulta de expresiones regulares 'comienza con', entonces eso puede usar un índice. Lo mejor es ejecutar un explicar () para ver qué sucede.
Kyle Banker

35
Cuando no está anclado al comienzo de la cuerda, es algo costoso. Pero, de nuevo, también lo es una LIKEconsulta en SQL.
Emily

44
entonces, siempre y cuando esté anclado al comienzo de la cuerda, ¿está bien? genial entonces. ¿eso significa que necesitamos agregar ^
user4951

44
Agregaría 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%'

fuera: paulo, patric

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

fuera: paulo, patric

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

fuera: pedro


buen ejemplo! Estoy encontrando el final del cheque con espacio y encontré esto :) / $ /
Phuong

¿Cómo encuentras todas las entradas para el nombre? o el comodín para * en SQL? ¿Algo que hace select name from users;que solo enumera a todos los usuarios?
anon58192932

1
@ anon58192932 Para mostrar todas las entradas de solo el campo "nombre" en una tabla llamada "usuarios", puede usar el método project () estableciendo los valores de los campos que desea 1. Los campos que no se mencionan en project () no serán traído excepto _id. El campo _id se imprime de forma predeterminada, lo que puede suprimir al poner el valor 0 para _id dentro del método project (). Algo así como: db.collection.find (). Project ({name: 1, _id: 0}) .toArray (function (err, docs) {console.log (docs); callback (docs);}); Consulte esto: docs.mongodb.com/manual/tutorial/…
gauravparmar

282

En

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

tu puedes hacer:

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

2
funciona bien para la búsqueda entre mayúsculas y minúsculas, ¿podría decirme cómo puedo hacer que funcione para realizar una búsqueda que no distingue entre mayúsculas y minúsculas?
Tahir Yasin

Para qué sería la expresión regular%sometext%
Tahir Yasin

64
@TahirYasin si todavía te estás preguntando, la búsqueda que no distingue entre mayúsculas y minúsculas se haría así:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

Resolví en golang usando mgo simplemente código como este, selector: = bson.M {"technician": bson.M {"$ regex": tech}}
Sandun Priyanka

1
Siente que esta debería ser la respuesta aceptada. Es el más simple y elegante actualmente.
Brett84c

88

En PHP, puede usar el siguiente código:

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

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

1
Si su valor RegEx se origina a partir de la entrada del usuario (por ejemplo, un formulario de filtro) y no desea que el valor mismo se tome como un RegExp, puede aplicar preg_quote ().
Philipp Rieber

2
Me acabo de dar cuenta de esto, pero en realidad esta es la respuesta incorrecta, a pesar de que funciona es subóptimo, en su lugar debería usar el objeto de expresión regular BSON a través de MongoRegex, $ regex tiene problemas de compatibilidad con ciertos comandos como $ in
Sammaye

Esta sintaxis es útil si el valor se almacena en una variable, por lo que la consulta podría escribirse como (en Ruby):$collection.where(field => {"$regex" => value})
Donny Kurnia

Pero, ¿por qué no puedes usar literales de matriz?
Alper

53

Usarías regex para eso en mongo.

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


29
Creo que esto solo muestra documentos con un valor de nombre que comienza con "m"
JackAce

53

Ya hay muchas respuestas. Estoy dando diferentes tipos de requisitos y soluciones para la búsqueda de cadenas con expresiones regulares.

Puede hacerlo con expresiones regulares que contienen palabras, es decir, me gusta. También puede usar $options => ipara la búsqueda sin distinción entre mayúsculas y minúsculas

Contiene string

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

No contiene stringsolo con expresiones regulares

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

Caso exacto insensible string

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

Empezar con string

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

Terminar con string

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

Conserve esto como un marcador y como referencia para cualquier otra modificación que pueda necesitar.


37

Tienes 2 opciones:

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

o

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

En el segundo, tiene más opciones, como "i" en las opciones para encontrar usando mayúsculas y minúsculas. Y sobre la "cadena", puede usar como ". Cadena " (% cadena%) o "cadena. *" (Cadena%) y ". * Cadena) (% cadena) por ejemplo. Puede usar expresiones regulares como tu quieras

¡Disfrutar!


34

Si el uso de Node.js , se dice que se puede escribir lo siguiente:

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

Además , puedes escribir esto:

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

Sintaxis similar en Ruby:collection.where(field => Regexp.new(value))
Donny Kurnia

24

Ya tienes las respuestas, pero para que coincida la expresión regular con insensibilidad a mayúsculas y minúsculas

Puedes usar la siguiente consulta

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

En iel /m/icaso indica insensibilidad al caso y .pretty()proporciona una salida más bonita


pero ¿qué pasa si quiero establecer el valor dinámicamente aquí
KS

@KuldeepKoranga puede colocar cualquier valor dinámico en lugar de 'm'. Es eso lo que quieres.
The6thSense

var search="feacebook"Entonces, db.users.find ({ "name" : /search/i } )¿ cómo puedo configurar a continuación @ The6thSens Sí, pero ?
KS

@KuldeepKoranga tiene asignado el valor.
The6thSense

1
@KuldeepKoranga stackoverflow.com/questions/7790811/… ¿esto ayuda?
The6thSense

18

Para Mangosta en Node.js

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

13

Puede usar la nueva característica de 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"
    }
});

66
Tenga en cuenta que la búsqueda de texto de AFAIK Mongodb funciona en palabras completas solo de forma predeterminada, por lo que coincidirá con valores como "Esta es una cadena con texto", pero no "Esta es una cadena con subtexto". Entonces no es como el operador "LIKE" de sql.
rocketmonkeys

@Rocketmonkeys es verdad ... para algo como "operador LIKE" usarías el operador $ regex mongo.
cmarrero01

13

En el proyecto nodejs y use mangosta, use 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);
            });

¿Cómo puedo usar como consulta? He intentado esto pero no funciona:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammad Shahzad

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

Me salvas la vida, amigo. ¿Puedes explicarme poco qué es $ regex y $ opciones?
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'}; }¿Puedes ver por qué esto no funciona?
Muhammad Shahzad

así $regex: 'value' generar una expresión regular para el valor de búsqueda y $options: 'i'medios entre mayúsculas y minúsculas . Su código no funcionó debido a que utilizó mismo valor para diferentes propiedades y que actúan como y condición que no debe cumplir con su colección de base de datos.
Shaishab Roy

12

Para PHP Mongo Like.
Tuve varios problemas con php mongo como. descubrí que la concatenación de los parámetros de expresiones regulares ayuda en algunas situaciones con las que comienza PHP mongo find field . Pensé que publicaría aquí para contribuir al hilo más popular

p.ej

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)

Según las respuestas y comentarios anteriores, la búsqueda $ text (Index) dará una mejor solución con el punto de referencia en comparación con el método $ regex correcto. Para referencia, consulte este enlace stackoverflow.com/questions/10610131/… . ¿Es posible implementar el método de índice $ text con PHP y mongoDB?
sankar muniyappa

12

Usar plantillas literales con variables también funciona:

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


Esta es la búsqueda desde el inicio ex - si "firstname" contiene testlast y si busco por "last" no dará resultado.
Vikas Chauhan

11

Con MongoDB Compass, debe usar la sintaxis de modo estricto, como tal:

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

(En MongoDB Compass, es importante que use en "lugar de ')



10

En SQL, la consulta 'me gusta ' se ve así:

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

En la consola MongoDB, se ve así:

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

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

Además, el pretty()método incluirá en todos los lugares donde se produzca una estructura JSON formateada que sea más legible.


10

Regex son caros son proceso.

Otra forma es crear un índice de texto y luego buscarlo usando $search.

Cree un índice de texto de los campos que desea que se puedan buscar:

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

Busque una cadena en el índice de texto:

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

Solución perfecta ... Las expresiones regulares son demasiado caras. Trabajando con un conjunto de datos de 20 millones de documentos y la diferencia de rendimiento es muy muy notable (lo cual es un eufemismo)
nivensookharan

1
De hecho, esto solo funciona para palabras completas, ver docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

En Go y el controlador mgo:

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

donde resultado es la instancia de estructura del tipo buscado


2
pls evitar campos sin codificar en los literales, no bson:RegEx{Pattern:"m", Options:"i"}en su lugar
bithavoc

8

Use expresiones regulares que coincidan como a continuación. La 'i' muestra insensibilidad a mayúsculas y minúsculas.

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 Mery sería como se muestra a continuación

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

para 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

Parece que hay razones para usar tanto el /regex_pattern/patrón javascript como el {'$regex': 'regex_pattern'}patrón mongo . Ver: Restricciones de sintaxis de RegEx de MongoBD

Este no es un tutorial completo de RegEx, pero me inspiré para ejecutar estas pruebas después de ver una publicación ambigua muy votada arriba .

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

Si está utilizando Spring-Data Mongodb, puede hacerlo de esta manera:

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

4

Como Mongo shell admite regex, eso es completamente posible.

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

Si queremos que la consulta no distinga entre mayúsculas y minúsculas, podemos usar la opción "i", como se muestra a continuación:

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


4

Utilice la búsqueda de subcadenas de agregación (con índice !!!):

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

¡bonito! ¿Hay alguna manera de hacer coincidir todo el documento? o hacer que el marco de agregación haga una consulta de seguimiento para hacer eso? Por el momento se ve un partido:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

en $ etapa del proyecto solo proyecta lo que quieres
Vokail

4

Cadena 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

Encontré una herramienta gratuita para traducir consultas MYSQL a MongoDB. http://www.querymongo.com/ Lo comprobé con varias consultas. como veo casi todos ellos son correctos. Según eso, la respuesta es

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

2

MongoRegex ha quedado en desuso.
Utilice MongoDB \ BSON \ Regex

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

Es importante tener en cuenta que esto se refiere a la clase MongoRegex en PHP . No es muy relevante para esta pregunta que trata sobre Node. Esto probablemente debería ser un comentario o mejor aún: una pregunta auto respondida en una publicación separada.
Boaz - Restablece a Mónica

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

Cuando buscamos patrones de cadena, siempre es mejor usar el patrón anterior como cuando no estamos seguros del caso. ¡¡¡Espero que ayude!!!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.