Definición
Sintaxis
La $regexFindAll el operador tiene la siguiente sintaxis:
{ $regexFindAll: { input: <expression> , regex: <expression>, options: <expression> } }
Campo | Descripción | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
La string a la que deseas aplicar el patrón regex. Puede ser un string o cualquier expresión válida que se resuelva en un string. | |||||||||||
El patrón regex a aplicar. Puede ser cualquier expresión válida que se resuelva en una string o patrón regex
Alternativamente, también puedes especificar las opciones de regex en el campo opciones. Para especificar las opciones No se pueden especificar opciones tanto en el campo | |||||||||||
Opcional. Los siguientes No se pueden especificar opciones tanto en el campo
|
Devuelve
El operador devuelve un arreglo:
Si el operador no encuentra una coincidencia, devuelve una matriz vacía.
Si el operador encuentra una coincidencia, devuelve una matriz de documentos que contiene la siguiente información para cada coincidencia:
la cadena coincidente en la entrada,
el punto de códigoíndice (no índice de bytes) de la cadena coincidente en la entrada, y
Un arreglo de strings que corresponde a los grupos capturados por la string coincidente. Los grupos de captura se especifican con paréntesis sin escape
()en el patrón regex.
[ { "match" : <string>, "idx" : <num>, "captures" : <array of strings> }, ... ]
Comportamiento
librería PCRE
A partir de la versión 6.1, MongoDB utiliza la librería PCRE2 (Perl Compatible Regular Expressions) para implementar la coincidencia de patrones de expresiones regulares. Para obtener más información sobre PCRE2, consulta la documentación de PCRE.
$regexFindAll y intercalación
La coincidencia de cadenas $regexFindAll para siempre distingue entre mayúsculas y minúsculas y signos diacríticos. $regexFindAll ignora la intercalación especificada para la colección,, y el índice, si sedb.collection.aggregate() utiliza.
Por ejemplo, crear una colección con una fuerza de intercalación 1, lo que significa que la intercalación solo compara caracteres base y no toma en cuenta diferencias como mayúsculas y diacríticos:
db.createCollection( "restaurants", { collation: { locale: "fr", strength: 1 } } )
Inserte los siguientes documentos:
db.restaurants.insertMany( [ { _id: 1, category: "café", status: "Open" }, { _id: 2, category: "cafe", status: "open" }, { _id: 3, category: "cafE", status: "open" } ] )
Lo siguiente utiliza la intercalación de la colección para realizar una coincidencia sin distinción entre mayúsculas y minúsculas y sin sensibilidad a los signos diacríticos:
db.restaurants.aggregate( [ { $match: { category: "cafe" } } ] )
[ { _id: 1, category: 'café', status: 'Open' }, { _id: 2, category: 'cafe', status: 'open' }, { _id: 3, category: 'cafE', status: 'open' } ]
Sin embargo, $regexFindAll ignora la intercalación. Los siguientes ejemplos de coincidencias de patrones de expresiones regulares distinguen entre mayúsculas y minúsculas y entre diacríticos:
db.restaurants.aggregate( [ { $addFields: { resultObject: { $regexFindAll: { input: "$category", regex: /cafe/ } } } } ] ) db.restaurants.aggregate( [ { $addFields: { resultObject: { $regexFindAll: { input: "$category", regex: /cafe/ } } } } ], { collation: { locale: "fr", strength: 1 } } // Ignored in the $regexFindAll )
Ambas operaciones devuelven lo siguiente:
{ "_id" : 1, "category" : "café", "resultObject" : null } { "_id" : 2, "category" : "cafe", "resultObject" : { "match" : "cafe", "idx" : 0, "captures" : [ ] } } { "_id" : 3, "category" : "cafE", "resultObject" : null }
Debido a que la query ignora la intercalación, requiere una coincidencia exacta en la string category (incluyendo mayúsculas y signos diacríticos), lo que significa que solo se empareja el documento _id: 2.
Para realizar una coincidencia de patrón regex que no distinga entre mayúsculas y minúsculas, utiliza la i Opción en su lugar. Ver i Opción para un ejemplo.
captures Comportamiento de la salida
Si tu patrón de regex contiene grupos de captura y el patrón encuentra una coincidencia en la entrada, el arreglo captures en los resultados corresponde a los grupos capturados por la string coincidente. Los grupos de captura se especifican con paréntesis sin escape () en el patrón regex. La longitud del arreglo captures es igual al número de grupos de captura en el patrón y el orden del arreglo coincide con el orden en que aparecen los grupos de captura.
Crea una colección de muestra llamada contacts con los siguientes documentos:
db.contacts.insertMany([ { "_id": 1, "fname": "Carol", "lname": "Smith", "phone": "718-555-0113" }, { "_id": 2, "fname": "Daryl", "lname": "Doe", "phone": "212-555-8832" }, { "_id": 3, "fname": "Polly", "lname": "Andrews", "phone": "208-555-1932" }, { "_id": 4, "fname": "Colleen", "lname": "Duncan", "phone": "775-555-0187" }, { "_id": 5, "fname": "Luna", "lname": "Clarke", "phone": "917-555-4414" } ])
La siguiente pipeline aplica el regex patrón /(C(ar)*)ol/ al campo fname:
db.contacts.aggregate([ { $project: { returnObject: { $regexFindAll: { input: "$fname", regex: /(C(ar)*)ol/ } } } } ])
El patrón regex encuentra una coincidencia con fname valores Carol y Colleen:
{ "_id" : 1, "returnObject" : [ { "match" : "Carol", "idx" : 0, "captures" : [ "Car", "ar" ] } ] } { "_id" : 2, "returnObject" : [ ] } { "_id" : 3, "returnObject" : [ ] } { "_id" : 4, "returnObject" : [ { "match" : "Col", "idx" : 0, "captures" : [ "C", null ] } ] } { "_id" : 5, "returnObject" : [ ] }
El patrón contiene el grupo de captura,(C(ar)*) que a su vez contiene el grupo (ar) anidado. Los elementos de la captures matriz corresponden a ambos grupos de captura. Si un documento coincidente no es capturado por un grupo (p. ej., Colleen y el (ar) grupo), reemplaza el grupo con un marcador de posición$regexFindAll nulo.
Como se muestra en el ejemplo anterior, el arreglo captures contiene un elemento para cada grupo de captura (utilizando null para los que no son de captura). Considere el siguiente ejemplo que busca números de teléfono con códigos de área de la ciudad de Nueva York aplicando un or lógico de grupos de captura al campo phone. Cada grupo representa un código de área de la Ciudad de Nueva York:
db.contacts.aggregate([ { $project: { nycContacts: { $regexFindAll: { input: "$phone", regex: /^(718).*|^(212).*|^(917).*/ } } } } ])
Para los documentos que coinciden con el patrón regex, el arreglo captures incluye el grupo de captura coincidente y reemplaza cualquier grupo no coincidente por null:
{ "_id" : 1, "nycContacts" : [ { "match" : "718-555-0113", "idx" : 0, "captures" : [ "718", null, null ] } ] } { "_id" : 2, "nycContacts" : [ { "match" : "212-555-8832", "idx" : 0, "captures" : [ null, "212", null ] } ] } { "_id" : 3, "nycContacts" : [ ] } { "_id" : 4, "nycContacts" : [ ] } { "_id" : 5, "nycContacts" : [ { "match" : "917-555-4414", "idx" : 0, "captures" : [ null, null, "917" ] } ] }
Ejemplos
$regexFindAll y sus opciones
Para ilustrar el comportamiento del operador como se analiza en este ejemplo, cree una colección de $regexFindAll muestra products con los siguientes documentos:
db.products.insertMany([ { _id: 1, description: "Single LINE description." }, { _id: 2, description: "First lines\nsecond line" }, { _id: 3, description: "Many spaces before line" }, { _id: 4, description: "Multiple\nline descriptions" }, { _id: 5, description: "anchors, links and hyperlinks" }, { _id: 6, description: "métier work vocation" } ])
De forma predeterminada, realiza una coincidencia que distingue entre mayúsculas y minúsculas. $regexFindAll Por ejemplo, la siguiente agregación realiza una que distingue entre mayúsculas y $regexFindAll minúsculas en el description campo. El patrón de expresión regular /line/ no especifica ninguna agrupación:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /line/ } } } } ])
La operación devuelve lo siguiente:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ ]}, { "match" : "line", "idx" : 19, "captures" : [ ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
El siguiente patrón de expresiones regulares /lin(e|k)/ especifica una agrupación (e|k) en el patrón:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /lin(e|k)/ } } } } ])
La operación devuelve lo siguiente:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject": [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ "e" ] }, { "match" : "line", "idx" : 19, "captures" : [ "e" ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ "e" ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ "e" ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ { "match" : "link", "idx" : 9, "captures" : [ "k" ] }, { "match" : "link", "idx" : 24, "captures" : [ "k" ] } ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
En la opción de retorno, el campo idx es el punto de código índice y no el índice de bytes. Para ilustrar, considera el siguiente ejemplo que utiliza el patrón regex /tier/:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /tier/ } } } } ])
La operación devuelve lo siguiente, donde solo el último registro coincide con el patrón y el idx devuelto es 2 (en lugar de 3 si se usa un índice de bytes)
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ { "match" : "tier", "idx" : 2, "captures" : [ ] } ] }
i Opción
Nota
No se pueden especificar opciones tanto en el campo regex como en el options.
Para realizar una coincidencia de patrones sindistinguir entre mayúsculas y minúsculas, incluya la opción i como parte del campo de expresión regular o en el campo de opciones:
// Specify i as part of the regex field { $regexFindAll: { input: "$description", regex: /line/i } } // Specify i in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "i" } } { $regexFindAll: { input: "$description", regex: "line", options: "i" } }
Por ejemplo, la siguiente agregación realiza un en $regexFindAll el description campo. No distingue entre mayúsculas y minúsculas. El patrón de expresión regular /line/ no especifica ningún agrupamiento:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /line/i } } } } ])
La operación devuelve los siguientes documentos:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ { "match" : "LINE", "idx" : 7, "captures" : [ ] } ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ ] }, { "match" : "line", "idx" : 19, "captures" : [ ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
m Opción
Nota
No se pueden especificar opciones tanto en el campo regex como en el options.
Para que coincida con los anclajes especificados (por ejemplo, ^, $) para cada línea de una string multilínea, incluya la opción m como parte del campo regex o en el campo opciones:
// Specify m as part of the regex field { $regexFindAll: { input: "$description", regex: /line/m } } // Specify m in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "m" } } { $regexFindAll: { input: "$description", regex: "line", options: "m" } }
El siguiente ejemplo incluye tanto las opciones i como m para hacer coincidir las líneas que comienzan con la letra s o S en cadenas multilínea:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /^s/im } } } } ])
La operación devuelve lo siguiente:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ { "match" : "S", "idx" : 0, "captures" : [ ] } ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "s", "idx" : 12, "captures" : [ ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
x Opción
Nota
No se pueden especificar opciones tanto en el campo regex como en el options.
Para ignorar todos los caracteres de espacio en blanco y comentarios sin escape (denotados por el carácter hash # sin escape y el siguiente carácter de nueva línea) en el patrón, incluya la opción s en el campo de opciones:
// Specify x in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "x" } } { $regexFindAll: { input: "$description", regex: "line", options: "x" } }
El siguiente ejemplo incluye la opción x para omitir espacios en blanco y comentarios sin escape:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /lin(e|k) # matches line or link/, options:"x" } } } } ])
La operación devuelve lo siguiente:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ "e" ] }, { "match" : "line", "idx" : 19, "captures" : [ "e" ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ "e" ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ "e" ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ { "match" : "link", "idx" : 9, "captures" : [ "k" ] }, { "match" : "link", "idx" : 24, "captures" : [ "k" ] } ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
s Opción
Nota
No se pueden especificar opciones tanto en el campo regex como en el options.
Para permitir el carácter de punto (es decir, .) en el patrón para hacer coincidir todos los caracteres, incluido el carácter de nueva línea, incluye la opción s en el campo opciones:
// Specify s in the options field { $regexFindAll: { input: "$description", regex: /m.*line/, options: "s" } } { $regexFindAll: { input: "$description", regex: "m.*line", options: "s" } }
El siguiente ejemplo incluye la opción s para permitir que el carácter de punto (es decir, .) coincida con todos los caracteres, incluyendo la nueva línea, así como la opción i para realizar una coincidencia sin distinción entre mayúsculas y minúsculas:
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex:/m.*line/, options: "si" } } } } ])
La operación devuelve lo siguiente:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "Many spaces before line", "idx" : 0, "captures" : [ ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "Multiple\nline", "idx" : 0, "captures" : [ ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
Utiliza $regexFindAll para analizar correos electrónicos de una string
Cree una colección de muestra feedback con los siguientes documentos:
db.feedback.insertMany([ { "_id" : 1, comment: "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com" }, { "_id" : 2, comment: "I wanted to concatenate a string" }, { "_id" : 3, comment: "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com" }, { "_id" : 4, comment: "It's just me. I'm testing. fred@MongoDB.com" } ])
La siguiente agregación utiliza para extraer todos los correos electrónicos $regexFindAll del comment campo (sin distinguir entre mayúsculas y minúsculas).
db.feedback.aggregate( [ { $addFields: { "email": { $regexFindAll: { input: "$comment", regex: /[a-z0-9_.+-]+@[a-z0-9_.+-]+\.[a-z0-9_.+-]+/i } } } }, { $set: { email: "$email.match"} } ] )
- Primera etapa
La etapa usa la etapa para agregar un nuevo
$addFieldscampoemailal documento. El nuevo campo es una matriz que contiene el resultado de ejecutar la operación en$regexFindAllelcommentcampo:{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "email" : [ { "match" : "aunt.arc.tica@example.com", "idx" : 38, "captures" : [ ] } ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "email" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "email" : [ { "match" : "cam@mongodb.com", "idx" : 56, "captures" : [ ] }, { "match" : "c.dia@mongodb.com", "idx" : 75, "captures" : [ ] } ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "email" : [ { "match" : "fred@MongoDB.com", "idx" : 28, "captures" : [ ] } ] } - Segunda etapa
La etapa utiliza la etapa
$setpara restablecer los elementos de arregloemaila los valores"email.match". Si el valor actual deemailes nulo, el nuevo valor deemailse establece en nulo.{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "email" : [ "aunt.arc.tica@example.com" ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "email" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "email" : [ "cam@mongodb.com", "c.dia@mongodb.com" ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "email" : [ "fred@MongoDB.com" ] }
Utiliza agrupaciones capturadas para analizar el nombre de usuario
Cree una colección de muestra feedback con los siguientes documentos:
db.feedback.insertMany([ { "_id" : 1, comment: "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com" }, { "_id" : 2, comment: "I wanted to concatenate a string" }, { "_id" : 3, comment: "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com" }, { "_id" : 4, comment: "It's just me. I'm testing. fred@MongoDB.com" } ])
Para responder a los comentarios, supongamos que desea analizar la parte local de la dirección de correo electrónico para usarla como nombre en los saludos. Usando el captured campo devuelto en los $regexFindAll resultados, puede analizar la parte local de cada dirección de correo electrónico:
db.feedback.aggregate( [ { $addFields: { "names": { $regexFindAll: { input: "$comment", regex: /([a-z0-9_.+-]+)@[a-z0-9_.+-]+\.[a-z0-9_.+-]+/i } }, } }, { $set: { names: { $reduce: { input: "$names.captures", initialValue: [ ], in: { $concatArrays: [ "$$value", "$$this" ] } } } } } ] )
- Primera etapa
La etapa usa la etapa para agregar un nuevo
$addFieldscamponamesal documento. El nuevo campo contiene el resultado de ejecutar la operación en$regexFindAllelcommentcampo:{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "names" : [ { "match" : "aunt.arc.tica@example.com", "idx" : 38, "captures" : [ "aunt.arc.tica" ] } ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "names" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "names" : [ { "match" : "cam@mongodb.com", "idx" : 56, "captures" : [ "cam" ] }, { "match" : "c.dia@mongodb.com", "idx" : 75, "captures" : [ "c.dia" ] } ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "names" : [ { "match" : "fred@MongoDB.com", "idx" : 28, "captures" : [ "fred" ] } ] } - Segunda etapa
El escenario usa el escenario
$setcon el operador$reducepara restablecernamesa un arreglo que contenga los elementos"$names.captures".{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "names" : [ "aunt.arc.tica" ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "names" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "names" : [ "cam", "c.dia" ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "names" : [ "fred" ] }
Tip
Para obtener más información sobre el comportamiento del arreglo captures y ejemplos adicionales, consulta Comportamiento de salidacaptures.