Definição
- $regexFindAll
- Fornece capacidade de correspondência de padrões de expressões regulares (regex) em expressões de aggregation. O operador retorna uma array de documentos que contém informações sobre cada correspondência. Se uma correspondência não for encontrada, retorna uma array vazia. - O MongoDB usa expressões regulares compatíveis com Perl (ou seja, "PCRE") versão 8.41 com suporte a UTF-8. 
Sintaxe
O operador $regexFindAll tem a seguinte sintaxe:
{ $regexFindAll: { input: <expression> , regex: <expression>, options: <expression> } } 
| Campo | Descrição | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| A string na qual você deseja aplicar o padrão regex. Pode ser uma string ou qualquer expressão válida que resolva para uma string. | |||||||||||
| O padrão regex a aplicar. Pode ser qualquer expressão válida que produza uma string ou padrão regex  
 Como alternativa, você também pode especificar as opções de regex com o  campo de opções. Para especificar as  Não é permitido especificar opções no campo  | |||||||||||
| Opcional. Os  Não é permitido especificar opções no campo  
 | 
Devoluções
O operador retorna uma array:
- Se o operador não encontrar uma correspondência, o operador retornará uma array vazia. 
- Se o operador encontrar uma correspondência, o operador retornará uma array de documentos que contém as seguintes informações para cada correspondência: - a string correspondente na entrada, 
- o índice do ponto de código (não índice de bytes) da string correspondente na entrada, e 
- Uma array das strings que corresponde aos grupos capturados pela string correspondente. Os grupos de captura são especificados com parênteses comuns - ()no padrão regex.
 - [ { "match" : <string>, "idx" : <num>, "captures" : <array of strings> }, ... ] 
Comportamento
$regexFindAll e Agrupamento
a correspondência de strings para $regexFindAll sempre diferencia maiúsculas, minúsculas e diacríticos. $regexFindAll ignora o agrupamento especificado para a coleção, db.collection.aggregate() e o índice, se utilizado.
Por exemplo, crie uma collection com força de agrupamento 1, o que significa que o agrupamento compara apenas caracteres básicos e ignora diferenças como letras maiúsculas, letras minúsculas e diacríticos:
db.createCollection( "restaurants", { collation: { locale: "fr", strength: 1 } } ) 
Insira os seguintes documentos:
db.restaurants.insertMany( [    { _id: 1, category: "café", status: "Open" },    { _id: 2, category: "cafe", status: "open" },    { _id: 3, category: "cafE", status: "open" } ] ) 
O seguinte usa o agrupamento da coleção para realizar uma correspondência insensível a maiúsculas e minúsculas e insensível a 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' } ] 
No entanto, $regexFindAll ignora o agrupamento. Os exemplos de correspondência de padrão de expressão regular a seguir diferenciam maiúsculas de minúsculas e 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 as operações retornam o seguinte:
{ "_id" : 1, "category" : "café", "resultObject" : null } { "_id" : 2, "category" : "cafe", "resultObject" : { "match" : "cafe", "idx" : 0, "captures" : [ ] } } { "_id" : 3, "category" : "cafE", "resultObject" : null } 
Como a query ignora o agrupamento, ela exige uma correspondência exata na string category (incluindo maiúsculas e minúsculas e acentos), o que significa que somente o documento _id: 2 corresponde.
Para executar uma correspondência de padrão regex sem distinção entre maiúsculas e minúsculas, use a opção i. Consulte Opção i para ver um exemplo.
captures Comportamento de Saída
Se o seu padrão regex contiver grupos de captura e o padrão encontrar uma correspondência na entrada, a array captures nos resultados corresponderá aos grupos capturados pela string correspondente. Os grupos de captura são especificados com parênteses sem escape () no padrão regex . O comprimento da array captures é igual ao número de grupos de captura no padrão e a ordem da array corresponde à ordem em que os grupos de captura aparecem.
Crie uma coleção de amostra denominada contacts com os seguintes 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" } ]) 
O pipeline a seguir aplica o padrão regex /(C(ar)*)ol/ ao campo fname:
db.contacts.aggregate([   {     $project: {       returnObject: {         $regexFindAll: { input: "$fname", regex: /(C(ar)*)ol/ }       }     }   } ]) 
O padrão regex encontra uma correspondência com valores de fname Carol e 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" : [ ] } 
O padrão contém o grupo de captura (C(ar)*) que contém o grupo aninhado (ar). Os elementos na array captures correspondem aos dois grupos de captura. Se um documento correspondente não for capturado por um grupo (por exemplo, Colleen e o grupo (ar)), $regexFindAll substitui o grupo por um espaço reservado nulo.
Conforme o exemplo anterior, a array captures contém um elemento para cada grupo de captura (utilizando null para não capturas). Considere o seguinte exemplo que procura números de telefone com códigos de área da cidade de Nova York ao aplicar um or lógico de grupos de captura no campo phone. Cada grupo representa um código de área da cidade de Nova York:
db.contacts.aggregate([   {     $project: {       nycContacts: {         $regexFindAll: { input: "$phone", regex: /^(718).*|^(212).*|^(917).*/ }       }     }   } ]) 
Para documentos que são correspondidos pelo padrão regex , a array captures inclui o grupo de captura correspondente e substitui quaisquer grupos que não sejam de captura 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" ] } ] } 
Exemplos
$regexFindAll e suas opções
Para ilustrar o comportamento do operador $regexFindAll como discutido neste exemplo, crie uma coleção de amostra products com os seguintes 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" } ]) 
Por padrão, $regexFindAll realiza uma correspondência com distinção entre maiúsculas e minúsculas. Por exemplo, a aggregation a seguir realiza uma que diferencia maiúsculas-minúsculas $regexFindAll no campo description. O padrão regex /line/ não especifica nenhum agrupamento:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /line/ } } } } ]) 
A operação retorna o seguinte:
{    "_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" : [ ] } 
O seguinte padrão regex /lin(e|k)/ especifica um agrupamento (e|k) no padrão:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /lin(e|k)/ } } } } ]) 
A operação retorna o seguinte:
{    "_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" : [ ] } 
Na opção de retorno, o idx campo é o índice ponto de código e não o índice de bytes. Para ilustrar, considere o seguinte exemplo que utiliza o padrão regex /tier/:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /tier/ } } } } ]) 
A operação retorna o seguinte onde somente o último registro corresponde ao padrão e o idx retornado é 2 (em vez de 3 se estiver utilizando um í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 Opção
Observação
Não é permitido especificar opções no campo regex e options.
Para executar a correspondência de padrãosem diferenciação de maiúsculas e minúsculas, inclua a opção i como parte do campo regex ou no campo options :
// 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 exemplo, a agregação a seguir executa um  $regexFindAll que não diferencia maiúsculas de minúsculas no campo description. O padrão regex /line/ não especifica nenhum agrupamento:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /line/i } } } } ]) 
A operação retorna os seguintes 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 Opção
Observação
Não é permitido especificar opções no campo regex e options.
Para corresponder às âncoras especificadas (por exemplo, ^, $) para cada linha de uma string de múltiplas linhas, inclua a opção m como parte do campo regex ou no campo opções:
// 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" } } 
O exemplo a seguir inclui as opções i e m para combinar linhas começando com a letra s ou S para strings de várias linhas:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /^s/im } } } } ]) 
A operação retorna o seguinte:
{    "_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 Opção
Observação
Não é permitido especificar opções no campo regex e options.
Para ignorar todos os caracteres de espaço em branco e comentários (indicados pelo caractere # de hash sem formato e pelo próximo caractere de nova linha) no padrão, inclua a opção s no campo opções:
// Specify x in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "x" } } { $regexFindAll: { input: "$description", regex: "line", options: "x" } } 
O exemplo a seguir inclui a opção x para ignorar espaços em branco e comentários sem escape:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /lin(e|k) # matches line or link/, options:"x" } } } } ]) 
A operação retorna o seguinte:
{    "_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 Opção
Observação
Não é permitido especificar opções no campo regex e options.
Para permitir o caractere ponto (ou seja, .) no padrão para corresponder a todos os caracteres, incluindo o novo caractere de linha, inclua a opção s no campo opções:
// Specify s in the options field { $regexFindAll: { input: "$description", regex: /m.*line/, options: "s" } } { $regexFindAll: { input: "$description", regex: "m.*line", options: "s" } } 
O exemplo a seguir inclui a opção s para permitir que o caractere do ponto (ou seja, .) corresponda a todos os caracteres, incluindo uma nova linha, bem como a opção i para realizar uma correspondência entre maiúsculas e minúsculas:
db.products.aggregate([    { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex:/m.*line/, options: "si"  } } } } ]) 
A operação retorna o seguinte:
{    "_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" : [ ] } 
Use $regexFindAll para analisar e-mails a partir de uma string string
Criar uma collection de amostra feedback com os seguintes 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" } ]) 
A agregação abaixo usa o $regexFindAll para extrair todos os e-mails do campo comment (sem distinção entre maiúsculas e 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"} } ] ) 
- Primeira etapa
- A etapa usa a etapa - $addFieldspara adicionar um novo campo- emailao documento. O novo campo é uma array que contém o resultado de executar o- $regexFindAllno campo- comment:- { "_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
- O estágio utiliza o estágio - $setpara redefinir os elementos de vetor do- emailpara o(s) valor(es)- "email.match". Se o valor atual de- emailfor nulo, o novo valor de- emailserá definido como 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" ] } 
Usar agrupamentos capturados para analisar o nome de usuário
Criar uma collection de amostra feedback com os seguintes 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 ao feedback, suponha que você queira analisar a parte local do endereço de e-mail para utilizar como o nome nas saudações. Utilizando o campo captured retornado nos resultados $regexFindAll, você pode analisar a parte local de cada endereço de e-mail:
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" ] } } } } } ] ) 
- Primeira etapa
- A etapa utiliza a etapa - $addFieldspara adicionar um novo campo- namesao documento. O novo campo contém o resultado da execução do- $regexFindAllno campo- comment:- { - "_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
- O estágio usa o estágio - $setcom o operador- $reducepara redefinir- namespara uma array que contém os 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" ] - } 
Dica
Para mais informações sobre o comportamento da array do captures e exemplos adicionais, consulte Comportamento de Saída docaptures .