对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

$regexFind(表达式操作符)

$regexFind

在聚合表达式中提供正则表达式 (regex) 模式匹配功能。如果找到匹配项,则返回包含第一个匹配项相关信息的文档。如果未找到匹配项,则返回 null。

The $regexFind operator has the following syntax:

{ $regexFind: { input: <expression> , regex: <expression>, options: <expression> } }
字段
说明

要应用正则表达式模式的字符串。可以是字符串或任何解析为字符串的有效表达式。

要应用的正则表达式模式。 可以是解析为字符串或正则表达式模式/<pattern>/的任何有效表达式。使用正则表达式/<pattern>/时,您还可以指定正则表达式选项im (但不能指定sx选项):

  • "pattern"

  • /<pattern>/

  • /<pattern>/<options>

或者,您也可以使用 选项字段指定 regex 选项。要指定sx 选项,必须使用 options字段。

不能同时在 regexoptions 字段中指定选项。

可选。以下 <options> 可用于正则表达式。

不能同时在 regexoptions 字段中指定选项。

选项
说明

i

大小写不敏感,可同时匹配大写和小写。可以在 options 字段中或作为正则表达式字段的一部分指定该选项。

m

对于包含锚点的模式(即 ^ 表示开头,$ 表示结尾),在每行的开头或结尾匹配具有多行值的字符串。如果没有此选项,这些锚点将匹配字符串的开头或结尾。

如果模式不包含锚点,或者字符串值没有换行符(如 \n),则 m 选项没有任何作用。

x

“扩展”功能将忽略模式中的所有空白字符,除非转义或包含在字符类中。

此外,其还会忽略未转义的哈希/磅 (#) 字符和下一新行(含)之间的字符,因此您可以在复杂的模式中加入注释。这种情况只适用于数据字符;空白字符绝不能出现在模式中的特殊字符序列中。

x 选项不影响对 VT 字符的处理(如代码 11)。

您只能在 options 字段中指定该选项。

s

允许点字符(即 .)匹配所有字符,包括换行符。

您只能在 options 字段中指定该选项。

该操作符如果未找到匹配项,则其结果为 null

如果操作符找到匹配项,则操作符的结果是一个包含以下内容的文档:

  • the first matching string in the input,

  • the code point index (not byte index) of the matching string in the input, and

  • 与匹配字符串所捕获群组对应的字符串数组。捕获群组在 regex 模式中用未转义括号 () 指定。

{ "match" : <string>, "idx" : <num>, "captures" : <array of strings> }

从版本 6.1 开始,MongoDB 使用 PCRE2(Perl 兼容正则表达式)库来实现正则表达式模式匹配。有关 PCRE2 的更多信息,请参阅 PCRE 文档。

$regexFind 的字符串匹配始终区分大小写和变音符号。 $regexFind 忽略为集合、db.collection.aggregate() 和索引指定的排序规则(如果使用)。

示例,创建一个排序规则强度为 1 的集合,这意味着排序规则仅比较基本字符,而忽略大小写和变音符号等差异:

db.createCollection( "restaurants", { collation: { locale: "fr", strength: 1 } } )

插入以下文档:

db.restaurants.insertMany( [
{ _id: 1, category: "café", status: "Open" },
{ _id: 2, category: "cafe", status: "open" },
{ _id: 3, category: "cafE", status: "open" }
] )

以下使用集合的排序规则来执行不区分大小写和不区分变音符号的匹配:

db.restaurants.aggregate( [ { $match: { category: "cafe" } } ] )
[
{ _id: 1, category: 'café', status: 'Open' },
{ _id: 2, category: 'cafe', status: 'open' },
{ _id: 3, category: 'cafE', status: 'open' }
]

但是,$regexFind 会忽略排序规则。以下正则表达式模式匹配示例区分大小写和变音符号:

db.restaurants.aggregate( [
{
$addFields: {
resultObject: { $regexFind: { input: "$category", regex: /cafe/ } }
}
}
] )
db.restaurants.aggregate( [
{
$addFields: {
resultObject: { $regexFind: { input: "$category", regex: /cafe/ } }
}
}
],
{ collation: { locale: "fr", strength: 1 } } // Ignored in the $regexFind
)

这两个操作都返回以下内容:

{ "_id" : 1, "category" : "café", "resultObject" : null }
{ "_id" : 2, "category" : "cafe", "resultObject" : { "match" : "cafe", "idx" : 0, "captures" : [ ] } }
{ "_id" : 3, "category" : "cafE", "resultObject" : null }

由于该查询忽略排序规则,因此需要与 category 字符串精确匹配(包括大小写和重音符号),这意味着只匹配文档_id: 2

To perform a case-insensitive regex pattern matching, use the i Option instead. See i Option for an example.

If your regex pattern contains capture groups and the pattern finds a match in the input, the captures array in the results corresponds to the groups captured by the matching string. Capture groups are specified with unescaped parentheses () in the regex pattern. The length of the captures array equals the number of capture groups in the pattern and the order of the array matches the order in which the capture groups appear.

创建一个包含以下文档的样本集合 contacts

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" }
])

The following pipeline applies the regex pattern /(C(ar)*)ol/ to the fname field:

db.contacts.aggregate([
{
$project: {
returnObject: {
$regexFind: { input: "$fname", regex: /(C(ar)*)ol/ }
}
}
}
])

The regex pattern finds a match with fname values Carol and Colleen:

{ "_id" : 1, "returnObject" : { "match" : "Carol", "idx" : 0, "captures" : [ "Car", "ar" ] } }
{ "_id" : 2, "returnObject" : null }
{ "_id" : 3, "returnObject" : null }
{ "_id" : 4, "returnObject" : { "match" : "Col", "idx" : 0, "captures" : [ "C", null ] } }
{ "_id" : 5, "returnObject" : null }

The pattern contains the capture group (C(ar)*) which contains the nested group (ar). The elements in the captures array correspond to the two capture groups. If a matching document is not captured by a group (e.g. Colleen and the group (ar)), $regexFind replaces the group with a null placeholder.

如上个示例所示,captures 数组为每个捕获组包含一个元素(对非捕获使用 null)。以下示例通过将捕获组的逻辑 or 应用到 phone 字段来搜索具有纽约市区号的电话号码。每组代表纽约市的一个区号:

db.contacts.aggregate([
{
$project: {
nycContacts: {
$regexFind: { input: "$phone", regex: /^(718).*|^(212).*|^(917).*/ }
}
}
}
])

For documents which are matched by the regex pattern, the captures array includes the matching capture group and replaces any non-capturing groups with 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" : null }
{ "_id" : 4, "nycContacts" : null }
{ "_id" : 5, "nycContacts" : { "match" : "917-555-4414", "idx" : 0, "captures" : [ null, null, "917" ] } }

To illustrate the behavior of the $regexFind operator as discussed in this example, create a sample collection products with the following documents:

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" }
])

By default, $regexFind performs a case-sensitive match. For example, the following aggregation performs a case-sensitive $regexFind on the description field. The regex pattern /line/ does not specify any grouping:

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex: /line/ } } } }
])

该操作返回以下内容:

{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : null }
{ "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : { "match" : "line", "idx" : 6, "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" : null }
{ "_id" : 6, "description" : "métier work vocation", "returnObject" : null }

以下正则表达式模式 /lin(e|k)/ 在模式中指定分组 (e|k)

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex: /lin(e|k)/ } } } }
])

该操作返回以下内容:

{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : null }
{ "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : { "match" : "line", "idx" : 6, "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" ] } }
{ "_id" : 6, "description" : "métier work vocation", "returnObject" : null }

In the return option, the idx field is the code point index and not the byte index. To illustrate, consider the following example that uses the regex pattern /tier/:

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex: /tier/ } } } }
])

该操作会返回以下内容,其中只有最后一条记录与模式匹配,并且返回的 idx2(如果使用字节索引,则返回 3)

{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : null }
{ "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : null }
{ "_id" : 3, "description" : "Many spaces before line", "returnObject" : null }
{ "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : null }
{ "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : null }
{ "_id" : 6, "description" : "métier work vocation",
"returnObject" : { "match" : "tier", "idx" : 2, "captures" : [ ] } }

注意

不能同时在 regexoptions 字段中指定选项。

要执行不区分大小写的模式匹配,将 i 选项作为正则表达式字段的一部分或纳入选项字段:

// Specify i as part of the regex field
{ $regexFind: { input: "$description", regex: /line/i } }
// Specify i in the options field
{ $regexFind: { input: "$description", regex: /line/, options: "i" } }
{ $regexFind: { input: "$description", regex: "line", options: "i" } }

For example, the following aggregation performs a case-insensitive $regexFind on the description field. The regex pattern /line/ does not specify any grouping:

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex: /line/i } } } }
])

该操作将返回以下文档:

{ "_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" : [ ] } }
{ "_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" : null }
{ "_id" : 6, "description" : "métier work vocation", "returnObject" : null }

注意

不能同时在 regexoptions 字段中指定选项。

要匹配多行字符串中每一行的指定锚点(如 ^$ ),请在 regex 字段或选项字段中包含 m 选项:

// Specify m as part of the regex field
{ $regexFind: { input: "$description", regex: /line/m } }
// Specify m in the options field
{ $regexFind: { input: "$description", regex: /line/, options: "m" } }
{ $regexFind: { input: "$description", regex: "line", options: "m" } }

以下示例同时包含 im 选项,用于为多行字符串匹配以字母 sS 开头的行:

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex: /^s/im } } } }
])

该操作返回以下内容:

{ "_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" : null }
{ "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : null }
{ "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : null }
{ "_id" : 6, "description" : "métier work vocation", "returnObject" : null }

注意

不能同时在 regexoptions 字段中指定选项。

要忽略模式中所有未转义的空格字符和注释(由未转义的哈希 # 字符和下一个换行符表示),请在选项字段中包含 s 选项:

// Specify x in the options field
{ $regexFind: { input: "$description", regex: /line/, options: "x" } }
{ $regexFind: { input: "$description", regex: "line", options: "x" } }

以下示例纳入 x 选项来跳过非转义空格和注释:

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex: /lin(e|k) # matches line or link/, options:"x" } } } }
])

该操作返回以下内容:

{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : null }
{ "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : { "match" : "line", "idx" : 6, "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" ] } }
{ "_id" : 6, "description" : "métier work vocation", "returnObject" : null }

注意

不能同时在 regexoptions 字段中指定选项。

要支持模式中的点字符(即 .)匹配包括换行符在内的所有字符,请在选项字段中加入 s 选项:

// Specify s in the options field
{ $regexFind: { input: "$description", regex: /m.*line/, options: "s" } }
{ $regexFind: { input: "$description", regex: "m.*line", options: "s" } }

下面的示例包含 s 选项,允许使用点字符(即“.”)来匹配包括新行在内的所有字符,以及使用 i 选项来执行不区分大小写的匹配:

db.products.aggregate([
{ $addFields: { returnObject: { $regexFind: { input: "$description", regex:/m.*line/, options: "si" } } } }
])

该操作返回以下内容:

{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : null }
{ "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : null }
{ "_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" : null }
{ "_id" : 6, "description" : "métier work vocation", "returnObject" : null }

使用以下文档创建样本collectionfeedback

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? cam@mongodb.com" },
{ "_id" : 4, comment: "It's just me. I'm testing. fred@MongoDB.com" }
])

The following aggregation uses the $regexFind to extract the email from the comment field (case insensitive).

db.feedback.aggregate( [
{ $addFields: {
"email": { $regexFind: { input: "$comment", regex: /[a-z0-9_.+-]+@[a-z0-9_.+-]+\.[a-z0-9_.+-]+/i } }
} },
{ $set: { email: "$email.match"} }
] )
第一个阶段:

The stage uses the $addFields stage to add a new field email to the document. The new field contains the result of performing the $regexFind on the comment field:

{ "_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" : null }
{ "_id" : 3, "comment" : "I can't find how to convert a date to string. cam@mongodb.com", "email" : { "match" : "cam@mongodb.com", "idx" : 46, "captures" : [ ] } }
{ "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "email" : { "match" : "fred@MongoDB.com", "idx" : 28, "captures" : [ ] } }
第二阶段

此阶段使用 $set 阶段将 email 重置为当前的 "$email.match" 值。如果 email 的当前值为 null,则会将 email 的新值设为 null。

{ "_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" }
{ "_id" : 3, "comment" : "I can't find how to convert a date to string. cam@mongodb.com", "email" : "cam@mongodb.com" }
{ "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "email" : "fred@MongoDB.com" }

使用以下文档创建样本collectioncontacts

db.contacts.insertMany([
{ "_id" : 1, name: "Aunt Arc Tikka", details: [ "+672-19-9999", "aunt.arc.tica@example.com" ] },
{ "_id" : 2, name: "Belle Gium", details: [ "+32-2-111-11-11", "belle.gium@example.com" ] },
{ "_id" : 3, name: "Cam Bo Dia", details: [ "+855-012-000-0000", "cam.bo.dia@example.com" ] },
{ "_id" : 4, name: "Fred", details: [ "+1-111-222-3333" ] }
])

The following aggregation uses the $regexFind to convert the details array into an embedded document with an email and phone fields:

db.contacts.aggregate( [
{ $unwind: "$details" },
{ $addFields: {
"regexemail": { $regexFind: { input: "$details", regex: /^[a-z0-9_.+-]+@[a-z0-9_.+-]+\.[a-z0-9_.+-]+$/, options: "i" } },
"regexphone": { $regexFind: { input: "$details", regex: /^[+]{0,1}[0-9]*\-?[0-9_\-]+$/ } }
} },
{ $project: { _id: 1, name: 1, details: { email: "$regexemail.match", phone: "$regexphone.match" } } },
{ $group: { _id: "$_id", name: { $first: "$name" }, details: { $mergeObjects: "$details"} } },
{ $sort: { _id: 1 } }
])
第一个阶段:

此阶段会将数组 $unwinds 为单个文档:

{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : "+672-19-9999" }
{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : "aunt.arc.tica@example.com" }
{ "_id" : 2, "name" : "Belle Gium", "details" : "+32-2-111-11-11" }
{ "_id" : 2, "name" : "Belle Gium", "details" : "belle.gium@example.com" }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : "+855-012-000-0000" }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : "cam.bo.dia@example.com" }
{ "_id" : 4, "name" : "Fred", "details" : "+1-111-222-3333" }
第二阶段

The stage uses the $addFields stage to add new fields to the document that contains the result of the $regexFind for phone number and email:

{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : "+672-19-9999", "regexemail" : null, "regexphone" : { "match" : "+672-19-9999", "idx" : 0, "captures" : [ ] } }
{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : "aunt.arc.tica@example.com", "regexemail" : { "match" : "aunt.arc.tica@example.com", "idx" : 0, "captures" : [ ] }, "regexphone" : null }
{ "_id" : 2, "name" : "Belle Gium", "details" : "+32-2-111-11-11", "regexemail" : null, "regexphone" : { "match" : "+32-2-111-11-11", "idx" : 0, "captures" : [ ] } }
{ "_id" : 2, "name" : "Belle Gium", "details" : "belle.gium@example.com", "regexemail" : { "match" : "belle.gium@example.com", "idx" : 0, "captures" : [ ] }, "regexphone" : null }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : "+855-012-000-0000", "regexemail" : null, "regexphone" : { "match" : "+855-012-000-0000", "idx" : 0, "captures" : [ ] } }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : "cam.bo.dia@example.com", "regexemail" : { "match" : "cam.bo.dia@example.com", "idx" : 0, "captures" : [ ] }, "regexphone" : null }
{ "_id" : 4, "name" : "Fred", "details" : "+1-111-222-3333", "regexemail" : null, "regexphone" : { "match" : "+1-111-222-3333", "idx" : 0, "captures" : [ ] } }
第三个阶段

该阶段使用$project阶段输出具有_id字段、name字段和details字段的文档。details字段设置为具有emailphone字段的文档,其值分别由regexemailregexphone字段确定。

{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : { "phone" : "+672-19-9999" } }
{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : { "email" : "aunt.arc.tica@example.com" } }
{ "_id" : 2, "name" : "Belle Gium", "details" : { "phone" : "+32-2-111-11-11" } }
{ "_id" : 2, "name" : "Belle Gium", "details" : { "email" : "belle.gium@example.com" } }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : { "phone" : "+855-012-000-0000" } }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : { "email" : "cam.bo.dia@example.com" } }
{ "_id" : 4, "name" : "Fred", "details" : { "phone" : "+1-111-222-3333" } }
第四阶段

该阶段使用$group阶段按输入文档的_id值对输入文档进行分组。该阶段使用$mergeObjects表达式来合并details文档。

{ "_id" : 3, "name" : "Cam Bo Dia", "details" : { "phone" : "+855-012-000-0000", "email" : "cam.bo.dia@example.com" } }
{ "_id" : 4, "name" : "Fred", "details" : { "phone" : "+1-111-222-3333" } }
{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : { "phone" : "+672-19-9999", "email" : "aunt.arc.tica@example.com" } }
{ "_id" : 2, "name" : "Belle Gium", "details" : { "phone" : "+32-2-111-11-11", "email" : "belle.gium@example.com" } }
第五阶段

该阶段使用 $sort 阶段按 _id 字段对文档排序。

{ "_id" : 1, "name" : "Aunt Arc Tikka", "details" : { "phone" : "+672-19-9999", "email" : "aunt.arc.tica@example.com" } }
{ "_id" : 2, "name" : "Belle Gium", "details" : { "phone" : "+32-2-111-11-11", "email" : "belle.gium@example.com" } }
{ "_id" : 3, "name" : "Cam Bo Dia", "details" : { "phone" : "+855-012-000-0000", "email" : "cam.bo.dia@example.com" } }
{ "_id" : 4, "name" : "Fred", "details" : { "phone" : "+1-111-222-3333" } }

使用以下文档创建样本collectionemployees

db.employees.insertMany([
{ "_id" : 1, name: "Aunt Arc Tikka", "email" : "aunt.tica@example.com" },
{ "_id" : 2, name: "Belle Gium", "email" : "belle.gium@example.com" },
{ "_id" : 3, name: "Cam Bo Dia", "email" : "cam.dia@example.com" },
{ "_id" : 4, name: "Fred" }
])

The employee email has the format <firstname>.<lastname>@example.com. Using the captured field returned in the $regexFind results, you can parse out user names for employees.

db.employees.aggregate( [
{ $addFields: {
"username": { $regexFind: { input: "$email", regex: /^([a-z0-9_.+-]+)@[a-z0-9_.+-]+\.[a-z0-9_.+-]+$/, options: "i" } },
} },
{ $set: { username: { $arrayElemAt: [ "$username.captures", 0 ] } } }
] )
第一个阶段:

The stage uses the $addFields stage to add a new field username to the document. The new field contains the result of performing the $regexFind on the email field:

{ "_id" : 1, "name" : "Aunt Arc Tikka", "email" : "aunt.tica@example.com", "username" : { "match" : "aunt.tica@example.com", "idx" : 0, "captures" : [ "aunt.tica" ] } }
{ "_id" : 2, "name" : "Belle Gium", "email" : "belle.gium@example.com", "username" : { "match" : "belle.gium@example.com", "idx" : 0, "captures" : [ "belle.gium" ] } }
{ "_id" : 3, "name" : "Cam Bo Dia", "email" : "cam.dia@example.com", "username" : { "match" : "cam.dia@example.com", "idx" : 0, "captures" : [ "cam.dia" ] } }
{ "_id" : 4, "name" : "Fred", "username" : null }
第二阶段

此阶段使用 $set 阶段将 username 重置为 "$username.captures" 数组的第零个元素。如果 username 的当前值为 null,则会将 username 的新值设为 null。

{ "_id" : 1, "name" : "Aunt Arc Tikka", "email" : "aunt.tica@example.com", "username" : "aunt.tica" }
{ "_id" : 2, "name" : "Belle Gium", "email" : "belle.gium@example.com", "username" : "belle.gium" }
{ "_id" : 3, "name" : "Cam Bo Dia", "email" : "cam.dia@example.com", "username" : "cam.dia" }
{ "_id" : 4, "name" : "Fred", "username" : null }

提示

For more information on the behavior of the captures array and additional examples, see captures Output Behavior.

给本页内容打分