$regexFindAll (agregação)
Nesta página
Definição
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 ponto de código índice (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
Biblioteca CRE
A partir da versão 6.1, o MongoDB usa a biblioteca PCRE2 (Perl Compatible Regular Expressions) para implementar a correspondência de padrões de expressão regular. Para saber mais sobre PCRE2, consulte a documentação do PCRE.
$regexFindAll
e agrupamento
$regexFindAll
ignora o agrupamento especificado para a coleção, db.collection.aggregate()
e o índice, se utilizado.
Por exemplo, crie uma coleção de amostras com força de agrupamento 1
(ou seja, comparar somente o caráter base e ignorar outras diferenças, como caso e diacríticos):
db.createCollection( "myColl", { collation: { locale: "fr", strength: 1 } } )
Insira os seguintes documentos:
db.myColl.insertMany([ { _id: 1, category: "café" }, { _id: 2, category: "cafe" }, { _id: 3, category: "cafE" } ])
Usando o agrupamento da coleção, a operação a seguir executa uma correspondência sem distinção entre maiúsculas e minúsculas e sem distinção entre diacríticos:
db.myColl.aggregate( [ { $match: { category: "cafe" } } ] )
A operação retorna os seguintes 3 documentos:
{ "_id" : 1, "category" : "café" } { "_id" : 2, "category" : "cafe" } { "_id" : 3, "category" : "cafE" }
No entanto, a expressão de aggregation $regexFind
ignora o agrupamento; ou seja, os exemplos de correspondência de padrão de expressão regular a seguir diferenciam maiúsculas de minúsculas e diacríticos:
db.myColl.aggregate( [ { $addFields: { results: { $regexFindAll: { input: "$category", regex: /cafe/ } } } } ] ) db.myColl.aggregate( [ { $addFields: { results: { $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é", "results" : [ ] } { "_id" : 2, "category" : "cafe", "results" : [ { "match" : "cafe", "idx" : 0, "captures" : [ ] } ] } { "_id" : 3, "category" : "cafE", "results" : [ ] }
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
$addFields
para adicionar um novo campoemail
ao documento. O novo campo é uma array que contém o resultado de executar o$regexFindAll
no campocomment
:{ "_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
$set
para redefinir os elementos de vetor doemail
para o(s) valor(es)"email.match"
. Se o valor atual deemail
for nulo, o novo valor deemail
será 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
$addFields
para adicionar um novo camponames
ao documento. O novo campo contém o resultado da execução do$regexFindAll
no campocomment
:{ "_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
$set
com o operador$reduce
para redefinirnames
para 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
Veja também:
Para mais informações sobre o comportamento da array do captures
e exemplos adicionais, consulte Comportamento de Saída docaptures
.