记录一下工作中用到的 mongodb 复杂查询
aggregate
筛选
=== 等于
{
$match: { name: "bob" }
}
!== 不等于
{
$match: {
name: {
$ne: 'bob'
}
}
}
like %a% 模糊匹配
静态字符串匹配
{
$match: { name: /bo/ }
}
动态变量匹配
{
$match: { name: new BSONRegExp(`${keyword}`) }
}
and
name like %xx% and no like %xx%
{
$match: {
$and: [
{ "name": new BSONRegExp(`${keyword}`) },
{ "no": new BSONRegExp(`${keyword}`) },
],
},
}
or
name like %xx% or no like %xx%
{
$match: {
$or: [
{ "patient.name": new BSONRegExp(`${param.keyword}`) },
{ "patient.hospitalNo": new BSONRegExp(`${param.keyword}`) },
],
},
}
join 连表查询
基本连表
类似 sql 的 left out join 查询
{
$lookup: <MongoDBAggregateLookupType>{
from: "departmentManagers",
localField: "_id",
foreignField: "accountId",
as: "managedDepartments",
},
};
- $lookup:对同一个数据库中的未分片集合执行 left out join
- from:指定要执行联接的同一数据库中的集合名称
- localField:当前集合中的字段名称
- foreignField:from 集合中的外键字段名称
- as:追加到当前集合结果集中的字段名称(类型是 {}[])
join 出来的数组取第一个
{
$lookup: <MongoDBAggregateLookupType>{
from: "patients",
localField: "patientId",
foreignField: "_id",
as: "patients",
},
},
{
$set: {
patient: { $first: "$patients" },
id: "$_id",
},
},
{ $unset: ["patients", "_id"] },
- $set 向文档中添加新字段或覆盖已存在字段的值,$set stage 是 $addFields stage 的别名,这两个 stage 都相当于 $project stage,它显式地指定输入文档中的所有现有字段并添加新字段(即默认显示所有字段,通过 $set 再添加新字段或覆盖已有字段的值)
- $first 取数组中索引为 0 的项
- $patients/$_id 引用字段时需要用 $ 符号作为前缀,否则不会执行引用字段行为
- { $set: { patient: { $first: "$patients" }, id: "$_id" } } 添加/设置 patient 字段的值为 patients 字段索引为 0 项的值;添加/设置 id 字段的值为 _id 字段的值
- $unset 移除文档中的的字段,值类型可以是 string | string []
重命名对象数组中的字段名称
$project
默认隐藏所有字段,只有声明了的字段才会输出到结果集
{
$lookup: <MongoDBAggregateLookupType>{
from: "departments",
localField: "managedDepartments.departmentId",
foreignField: "_id",
as: "departments",
},
},
{
$project: {
departments: {
$map: {
input: "$departments",
as: "item",
in: {
id: "$$item._id",
name:"$$item.name",
},
},
},
},
}
输出:
[
{
"_id": "x",
"departments": [
{
"id": "xx",
"name: "bob"
}
]
}
]
- $project 将带有请求字段的文档传递到管道中的下一个阶段。指定的字段可以是输入文档中的现有字段,也可以是新计算的字段(只有 $project 里面声明了的字段才会输出到结果中)
- $map 将表达式应用于数组中的每个项,并返回包含应用结果的数组
- $map.input 解析为数组的表达式,这里示例中是 $departments,相当于引用集合中的 departments 字段,引用必须加 $ 前缀
- $map.as 可选的。表示输入数组中每个单独元素的变量的名称。如果没有指定名称,变量名默认为 this
- $map.in 应用于输入数组的每个元素的表达式。表达式使用as中指定的变量名单独引用每个元素(引用变量用 $$ 双美元符号)
$set
默认显示所有字段,再将 $set 中新声明的新字段追加到文档中
{
$lookup: <MongoDBAggregateLookupType>{
from: "departments",
localField: "managedDepartments.departmentId",
foreignField: "_id",
as: "departments",
},
},
{
$set: {
id: "$_id",
departments: {
$map: {
input: "$departments",
as: "item",
in: {
id: "$$item._id",
name: "$$item.name",
},
},
},
}
}
输出:
[
{
"_id": "x",
...其余字段
"departments": [
{
"id": "xx",
"name: "bob"
}
]
}
]