MongoDB 正则表达式教程
正则表达式用于模式匹配,基本上用于文档中的发现字符串。
有时,在检索集合中的文档时,你可能无法确切知道要搜索的确切字段值。因此,可以使用正则表达式来帮助基于模式匹配搜索值来检索数据。
在本教程中,你将学习 -
-
使用
$regex运算符进行模式匹配 -
与
$选项匹配的模式 -
没有正则表达式运算符的模式匹配
-
从集合中提取最后
n个文件
使用 $regex 运算符进行模式匹配
MongoDB 中的正则表达式运算符用于搜索集合中的特定字符串。以下示例显示了如何完成此操作。
假设我们有相同的 Employee 集合,其字段名称为 Employeeid 和 EmployeeName。我们也假设我们的藏品中有以下文件。
| 员工 ID | 员工姓名 |
|---|---|
| 22 | NewMartin |
| 2 | Mohan |
| 3 | Joe |
| 4 | MohanR |
| 100 | Tastones |
| 6 | Gurang |
在下面的代码中,我们使用了正则表达式运算符来指定搜索条件。
> db.Employee.find({EmployeeName : {$regex: "Gu"}}).foreach(printjson)
代码说明:
- 在这里,我们要查找所有其中包含字符
Gu的员工姓名。因此,我们指定$regex运算符来定义Gu的搜索条件 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)
代码说明:
- 在搜索条件中,我们使用的是
^和$字符。^用于确保字符串以特定字符开头,$用于确保字符串以特定字符结尾。因此,当代码执行时,它将仅获取名为Tastones的字符串。 - printjson 用于打印查询以更好的方式返回的每个文档。
如果命令执行成功,将显示以下输出:
输出:
> db.Employee.find({EmployeeName : {$regex: "^Tastones$" }}).forEach(printjson)
{
"_id" : ObjectId("563c4fbffa0d1cc156e17102"),
"Employeeid" : 100,
"EmployeeName" : "Tastones"
}
在输出中,可以清楚地看到字符串 Tastones 被取出。
与 $options 匹配的模式
使用正则表达式运算符时,还可以使用 $options 关键字提供其他选项。例如,假设你想要查找其员工姓名中包含 Gu 的所有文档,而不管它是区分大小写还是不区分大小写。如果需要这样的结果,那么我们需要使用 $options 和 case insensitivity 参数。
以下示例显示了如何完成此操作。
假设我们有相同的 Employee 集合,其字段名称为 Employeeid 和 EmployeeName。
我们也假设我们的集合中有以下文件。
| 员工 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)
代码说明:
- 带有
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"
}
- 输出清楚地表明,即使一个文档的大写字母为
Gu,文档仍会显示在结果集中。
没有正则表达式运算符的模式匹配
也可以在没有正则表达式运算符的情况下进行模式匹配。以下示例显示了如何完成此操作。
> db.Employee.find({EmployeeName: /Gu/}).forEach(printjson)
代码说明:
/../选项基本上意味着在这些分隔符中指定搜索条件。因此,我们指定/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 集合,其字段名称为 Employeeid 和 EmployeeName。
我们也假设我们的集合中有以下文件:
| 员工 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)
代码说明:
-
查询文档时,使用
sort函数根据集合中的_id 字段值以相反的顺序对记录进行排序。-1基本上表示以相反顺序或降序对文档进行排序,以使最后一个文档成为要显示的第一个文档。 -
然后使用 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 子句可用于限制返回的文档数。