MongoDB 正则表达式教程

正则表达式用于模式匹配,基本上用于文档中的发现字符串。

有时,在检索集合中的文档时,你可能无法确切知道要搜索的确切字段值。因此,可以使用正则表达式来帮助基于模式匹配搜索值来检索数据。

在本教程中,你将学习 -

  • 使用 $regex 运算符进行模式匹配

  • $ 选项匹配的模式

  • 没有正则表达式运算符的模式匹配

  • 从集合中提取最后 n 个文件

使用 $regex 运算符进行模式匹配

MongoDB 中的正则表达式运算符用于搜索集合中的特定字符串。以下示例显示了如何完成此操作。

假设我们有相同的 Employee 集合,其字段名称为 EmployeeidEmployeeName。我们也假设我们的藏品中有以下文件。

员工 ID 员工姓名
22 NewMartin
2 Mohan
3 Joe
4 MohanR
100 Tastones
6 Gurang

在下面的代码中,我们使用了正则表达式运算符来指定搜索条件。

> db.Employee.find({EmployeeName : {$regex: "Gu"}}).foreach(printjson)

代码说明:

  1. 在这里,我们要查找所有其中包含字符 Gu 的员工姓名。因此,我们指定 $regex 运算符来定义 Gu 的搜索条件
  2. printjson 用于打印查询以更好的方式返回的每个文档。

如果命令执行成功,将显示以下输出:

输出:

> db.Employee.find({EmployeeName : {$regex: "Gu" }}).forEach(printjson)
{
    "_id" : ObjectId("563c4fbffa0d1cc156e17102"), 
    "Employeeid" : 100,
    "EmployeeName" : "Guru99"
}
{
    "_id" : objectId("563c4fc8fa0d1cc156e17103"), 
    "Employeeid" : 6, 
    "EmployeeName" : "Gurang"
}

输出清楚地显示返回员工姓名包含 Gu 字符的那些文档。

如果你的集合中包含以下文档,并且其他文档中包含 员工名称Tastones9。如果你将搜索条件输入为 Tastones,它还将返回具有 Tastones9 的文档。但是假设我们不想要这个并且只想用 Tastones 返回文档。然后我们可以通过精确的模式匹配来完成要进行精确的模式匹配,我们将使用^和$字符。我们将在字符串的开头添加^字符,在字符串的末尾添加$。

员工 ID 员工姓名
22 NewMartin
2 Mohan
3 Joe
4 MohanR
100 Tastones
6 Gurang
8 Tastones9

以下示例显示了如何完成此操作。

> db.Employee.find({EmployeeName : {$regex: "^Tastones$" }}).forEach(printjson)

代码说明:

  1. 在搜索条件中,我们使用的是 ^$ 字符。 ^ 用于确保字符串以特定字符开头,$ 用于确保字符串以特定字符结尾。因此,当代码执行时,它将仅获取名为 Tastones 的字符串。
  2. printjson 用于打印查询以更好的方式返回的每个文档。

如果命令执行成功,将显示以下输出:

输出:

> db.Employee.find({EmployeeName : {$regex: "^Tastones$" }}).forEach(printjson)
{
    "_id" : ObjectId("563c4fbffa0d1cc156e17102"), 
    "Employeeid" : 100,
    "EmployeeName" : "Tastones"
}

在输出中,可以清楚地看到字符串 Tastones 被取出。

$options 匹配的模式

使用正则表达式运算符时,还可以使用 $options 关键字提供其他选项。例如,假设你想要查找其员工姓名中包含 Gu 的所有文档,而不管它是区分大小写还是不区分大小写。如果需要这样的结果,那么我们需要使用 $optionscase insensitivity 参数。

以下示例显示了如何完成此操作。

假设我们有相同的 Employee 集合,其字段名称为 EmployeeidEmployeeName

我们也假设我们的集合中有以下文件。

员工 ID 员工姓名
22 NewMartin
2 Mohan
3 Joe
4 MohanR
100 Tastones
6 Gurang
7 Guru99

现在,如果我们运行与上一个主题相同的查询,我们将永远不会在结果中看到带有 GURU99 的文档。为了确保在结果集中出现这种情况,我们需要添加 $options: 'I' 参数。

> db.Employee.find({EmployeeName:{$regex: "Gu", $options:'i' }}).forEach(printjson)

代码说明:

  1. 带有 i 参数的 $options(表示不区分大小写)指定我们要执行搜索,无论我们是否在大写或小写中找到字母 Gu

如果命令执行成功,将显示以下输出:

输出:

> db.Employee.find({EmployeeName: {$regex: "Gu", $options:'i'}}).forEach(printjson)
{
    "_id" : ObjectId("563c4fbffa0d1cc156e17102"), 
    "Employeeid" : 100, 
    "EmployeeName" : "Guru99",
}
{
    "_id" : objectId("563c4fc8fa0d1cc156e17103"), 
    "Employeeid" : 6, 
    "EmployeeName" : "Gurang"
}
{
    "_id" : ObjectId("563c52e8fa0d1cc156e17104"), 
    "Employeeid" : 7, 
    "EmployeeName" : "GURU99"
}
  1. 输出清楚地表明,即使一个文档的大写字母为 Gu,文档仍会显示在结果集中。

没有正则表达式运算符的模式匹配

也可以在没有正则表达式运算符的情况下进行模式匹配。以下示例显示了如何完成此操作。

> db.Employee.find({EmployeeName: /Gu/}).forEach(printjson)

代码说明:

  1. /../ 选项基本上意味着在这些分隔符中指定搜索条件。因此,我们指定 /Gu/ 找到那些在其 EmployeeName 中具有 Gu 的文档。

如果命令执行成功,将显示以下输出:

输出:

> db.Employee.find({EmployeeName: /Gu/}).forEach(printjson)
{
    "_id" : ObjectId("563c4fbffa0d1cc156e17102"), 
    "Employeeid" : 100, 
    "EmployeeName" : "Guru99",
}
{
    "_id" : objectId("563c4fc8fa0d1cc156e17103"), 
    "Employeeid" : 6, 
    "EmployeeName" : "Gurang"
}

输出清楚地显示返回员工姓名包含 Gu 字符的那些文档。

从集合中获取最后的 n 个文档

有多种方法可以在集合中获取最后 n 个文档。

让我们通过以下步骤来看看其中一种方法

以下示例显示了如何完成此操作。

假设我们有相同的 Employee 集合,其字段名称为 EmployeeidEmployeeName

我们也假设我们的集合中有以下文件:

员工 ID 员工姓名
22 NewMartin
2 Mohan
3 Joe
4 MohanR
100 Tastones
6 Gurang
7 GURU99
> db.Employee.find().sort({_id:-1}).limit(2).forEach(printjson)

代码说明:

  1. 查询文档时,使用 sort 函数根据集合中的_id 字段值以相反的顺序对记录进行排序。 -1 基本上表示以相反顺序或降序对文档进行排序,以使最后一个文档成为要显示的第一个文档。

  2. 然后使用 limit 子句只显示所需的记录数。这里我们设置了 limit(2),因此它将获取最后两个文档。

如果命令执行成功,将显示以下输出:

输出:

> db.Employee.find().sort({_id:-1}).limit(2).forEach(printjson)
{
    "_id" : ObjectId("563c4fbffa0d1cc156e17102"), 
    "Employeeid" : 100, 
    "EmployeeName" : "Guru99",
}
{
    "_id" : objectId("563c4fc8fa0d1cc156e17103"), 
    "Employeeid" : 6, 
    "EmployeeName" : "Gurang"
}

输出清楚地显示了集合中的最后两个文档。因此,我们已经清楚地表明,要获取集合中的最后 n 个文档,我们可以先按降序对文档进行排序,然后使用 limit 子句返回所需的 n 个文档。

注意:如果对大于 38,000 个字符的字符串执行搜索,则不会显示正确的结果。

概要:

  • $regex 运算符可以实现模式匹配。此运算符可用于查找集合中的某些字符串。
  • ^$ 符号可用于精确文本搜索,其中 ^ 用于确保字符串以特定字符开头,$ 用于确保字符串以特定字符结尾。
  • i$regex 运算符可用于指定不区分大小写,以便可以搜索字符串,无论它们是小写还是大写。
  • 分隔符 // 也可用于模式匹配。
  • 使用 sort 和 limit 函数的组合返回集合中的最后 n 个文档。sort 函数可用于按降序返回文档,之后 limit 子句可用于限制返回的文档数。