MongoDB comienza con consulta

Tahseen Tauseef 20 junio 2023
  1. MongoDB comienza con una consulta usando $regex
  2. Carácter de punto . para coincidir con la nueva línea
MongoDB comienza con consulta

En este artículo de MongoDB, el usuario aprenderá a comenzar con una consulta utilizando $regex. Proporciona capacidades de expresión regular para cadenas de coincidencia de patrones en consultas.

MongoDB comienza con una consulta usando $regex

Si desea utilizar $regex, utilice una de las siguientes sintaxis.

{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }

En MongoDB, el usuario también puede usar objetos de expresiones regulares (es decir, /patrón/) para especificar expresiones regulares.

{ <field>: /pattern/<options> }

El usuario puede utilizar expresiones regulares con las siguientes <opciones>.

Opción Descripción Restricciones de sintaxis
i Insensible a mayúsculas y minúsculas para hacer coincidir mayúsculas y minúsculas.
m Para cadenas con valores de varias líneas, haga coincidir el principio o el final de cada línea para los patrones que incluyen anclas como ^ al principio y $ al final. La opción m no tiene efecto si el patrón no tiene anclas o si el valor de la cadena no contiene caracteres de nueva línea (por ejemplo, \n).
x Todos los caracteres de espacio en blanco en el patrón $regex se ignoran a menos que se escapen o se incluyan en una clase de caracteres. También ignora los caracteres en el medio e incluye un carácter almohadilla/almohadilla sin escape (#) y la siguiente línea nueva, lo que le permite agregar comentarios en patrones complejos. Es posible que los espacios en blanco no aparezcan dentro de secuencias de caracteres especiales en un patrón; esto solo se refiere a los caracteres de datos. La opción x no afecta cómo se maneja el carácter VT (es decir, el código 11). Requerirá $regex con la sintaxis $options
s Permite que el carácter de punto (.) coincida con cualquier carácter, incluidas las líneas nuevas. Requiere la sintaxis $regex con $options

El operador $regex no admite el modificador de búsqueda global g.

la expresión $in

Solo se pueden usar objetos de expresión regular de JavaScript (es decir, /patrón/) para incorporar una expresión regular en la expresión de consulta $in. Considere el siguiente ejemplo.

{ name: { $in: [ /^acme/i, /^ack/ ] } }

Dentro de $in, no puede utilizar expresiones de operador $regex.

Condiciones implícitas Y para el campo

Utilice el operador $regex para incorporar una expresión regular en una lista separada por comas de criterios de consulta para el campo. Considere el siguiente ejemplo.

{ name: { $regex: /acme.*corp/i, $nin: [ 'acmeblahcorp' ] } }
{ name: { $regex: /acme.*corp/, $options: 'i', $nin: [ 'acmeblahcorp' ] } }
{ name: { $regex: 'acme.*corp', $options: 'i', $nin: [ 'acmeblahcorp' ] } }

el operador $regex con x y s

El usuario debe usar el operador $regex con el operador $opciones para usar las opciones x o s. Por ejemplo, para especificar las opciones i y s, debe utilizar $opciones.

{ name: { $regex: /acme.*corp/, $options: "si" } }
{ name: { $regex: 'acme.*corp', $options: "si" } }

PCRE frente a JavaScript

El usuario debe usar la expresión del operador $regex con el patrón como una cadena para aprovechar las funciones compatibles con PCRE en el patrón de expresiones regulares que no son compatibles con JavaScript.

Por ejemplo, debe usar el operador $regex con el patrón como una cadena para usar (?i) y (?-i) en el patrón para activar la distinción entre mayúsculas y minúsculas para el patrón restante.

{ name: { $regex: '(?i)a(?-i)cme' } }

$regex y $not

A partir de la versión 4.0.7, el operador $not puede realizar una operación lógica NOT en ambos:

  1. objetos de expresión regular (es decir, /patrón/)

    Por ejemplo:

db.inventory.find( { item: { $not: /^p.*/ } } )
  1. Expresiones del operador $regex (a partir de MongoDB 4.0.7).

    Por ejemplo:

db.inventory.find( { item: { $not: { $regex: "^p.*" } } } )
db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )

En la versión 4.0.6 y anteriores, podía usar el operador $not con objetos de expresión regular (es decir, /pattern/) pero no con las expresiones del operador $regex.

Si el campo tiene un índice, MongoDB compara la expresión regular con los valores del índice, lo que puede ser más rápido que un análisis de recopilación para consultas de expresiones regulares que distinguen entre mayúsculas y minúsculas.

Es posible una mayor optimización si la expresión regular tiene una expresión de prefijo, lo que indica que todas las posibles coincidencias comienzan con la cadena exacta. Esto permite que MongoDB cree un rango a partir del prefijo y solo coincida con los valores de índice dentro de ese rango.

Si una expresión regular comienza con un signo de intercalación (^) o un ancla izquierda (\A), seguida de una cadena de símbolos simples, se denomina expresión de prefijo. Por ejemplo, la expresión regular /^abc.*/ se optimizará haciendo coincidir solo los valores de índice que comienzan con abc.

Además, aunque /^a/, /^a.*/ y /^a.*$/ coinciden con cadenas comparables, su rendimiento es diferente.

Si existe un índice adecuado, todas estas expresiones lo utilizan; sin embargo, /^a.*/ y /^a.*$/ son más lentos. Después de hacer coincidir el prefijo, /^a/ puede detener la búsqueda.

Las consultas de expresiones regulares que no distinguen entre mayúsculas y minúsculas no pueden aprovechar los índices de manera eficiente. La implementación $regex, por ejemplo, no tiene en cuenta la intercalación y, por lo tanto, no puede usar índices que no distingan entre mayúsculas y minúsculas.

Ejemplos:

Los siguientes ejemplos utilizan una colección llamada productos con los siguientes documentos.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." },
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" },
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before     line" },
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }

la declaración ME GUSTA

Este ejemplo coincide con todos los documentos donde el campo ski es como "%789".

db.products.find( { ski: { $regex: /789$/ } } )

El ejemplo es similar a la siguiente instrucción SQL LIKE.

SELECT * FROM products
WHERE ski like "%789";

Coincidencia de expresiones regulares que no distingue entre mayúsculas y minúsculas

El siguiente ejemplo utiliza la opción i y realiza una coincidencia que no distingue entre mayúsculas y minúsculas para documentos con un valor ski que comienza con ABC.

db.products.find( { ski: { $regex: /^ABC/i } } )

La consulta coincide con los siguientes documentos.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }

Coincidencia de varias líneas

La opción m se usa en el siguiente ejemplo para hacer coincidir las líneas que comienzan con la letra S en cadenas de varias líneas.

db.products.find( { description: { $regex: /^S/, $options: 'm' } } )

La consulta coincide con los siguientes documentos que se indican a continuación.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }

Sin la opción m, la consulta solo coincidiría con el siguiente documento.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }

Si el patrón $regex no incluye un ancla, el patrón se aplica a toda la cadena, como en el siguiente ejemplo.

db.products.find( { description: { $regex: /S/ } } )

Entonces, el $regex coincidiría con ambos documentos.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }

Carácter de punto . para coincidir con la nueva línea

La opción s permite que el carácter de punto (.) coincida con todos los caracteres, incluida la nueva línea, y la opción i permite una coincidencia que no distingue entre mayúsculas y minúsculas.

db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )

La consulta coincide con los siguientes documentos.

{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before     line" }
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }

La consulta solo coincidiría con el siguiente documento sin la opción s.

{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before     line" }

Espacios en blanco en un patrón

En el patrón de coincidencia, la opción x ignora los espacios en blanco y los comentarios señalados con # y termina con n:..

var pattern = "abc #category code\n123 #item number"
db.products.find( { ski: { $regex: pattern, $options: "x" } } )

La consulta coincide con el siguiente documento.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }