记录一下工作中用到的 mongodb 复杂查询

aggregate

筛选

=== 等于

  1. {
  2. $match: { name: "bob" }
  3. }

!== 不等于

  1. {
  2. $match: {
  3. name: {
  4. $ne: 'bob'
  5. }
  6. }
  7. }

like %a% 模糊匹配

静态字符串匹配

  1. {
  2. $match: { name: /bo/ }
  3. }

动态变量匹配

  1. {
  2. $match: { name: new BSONRegExp(`${keyword}`) }
  3. }

and

name like %xx% and no like %xx%

  1. {
  2. $match: {
  3. $and: [
  4. { "name": new BSONRegExp(`${keyword}`) },
  5. { "no": new BSONRegExp(`${keyword}`) },
  6. ],
  7. },
  8. }

or

name like %xx% or no like %xx%

  1. {
  2. $match: {
  3. $or: [
  4. { "patient.name": new BSONRegExp(`${param.keyword}`) },
  5. { "patient.hospitalNo": new BSONRegExp(`${param.keyword}`) },
  6. ],
  7. },
  8. }

join 连表查询

基本连表

类似 sql 的 left out join 查询

  1. {
  2. $lookup: <MongoDBAggregateLookupType>{
  3. from: "departmentManagers",
  4. localField: "_id",
  5. foreignField: "accountId",
  6. as: "managedDepartments",
  7. },
  8. };
  • $lookup:对同一个数据库中的未分片集合执行 left out join
  • from:指定要执行联接的同一数据库中的集合名称
  • localField:当前集合中的字段名称
  • foreignField:from 集合中的外键字段名称
  • as:追加到当前集合结果集中的字段名称(类型是 {}[])

    join 出来的数组取第一个

    1. {
    2. $lookup: <MongoDBAggregateLookupType>{
    3. from: "patients",
    4. localField: "patientId",
    5. foreignField: "_id",
    6. as: "patients",
    7. },
    8. },
    9. {
    10. $set: {
    11. patient: { $first: "$patients" },
    12. id: "$_id",
    13. },
    14. },
    15. { $unset: ["patients", "_id"] },
  • $set stage 是 $addFields stage 的别名,这两个 stage 都相当于 $project stage,它显式地指定输入文档中的所有现有字段并添加新字段(即默认显示所有字段,通过 $set 再添加新字段或覆盖已有字段的值)

  • $first 取数组中索引为 0 的项
  • $patient | $_id 引用字段时需要用 $ 符号作为前缀,否则不会执行引用字段行为
  • { $set: { patient: { ⚗️ Pratical MongoDB Aggregation - 图1patients” }, id: “$_id” } } 添加/设置 patient 字段的值为 patients 字段索引为 0 项的值;添加/设置 id 字段的值为 _id 字段的值
  • $unset 移除文档中的的字段,值类型可以是 string | string []

    重命名对象数组中的字段名称

    $project

    默认隐藏所有字段,只有声明了的字段才会输出到结果集

    1. {
    2. $lookup: <MongoDBAggregateLookupType>{
    3. from: "departments",
    4. localField: "managedDepartments.departmentId",
    5. foreignField: "_id",
    6. as: "departments",
    7. },
    8. },
    9. {
    10. $project: {
    11. departments: {
    12. $map: {
    13. input: "$departments",
    14. as: "item",
    15. in: {
    16. id: "$$item._id",
    17. name:"$$item.name",
    18. },
    19. },
    20. },
    21. },
    22. }

    输出:

    1. [
    2. {
    3. "_id": "x",
    4. "departments": [
    5. {
    6. "id": "xx",
    7. "name: "bob"
    8. }
    9. ]
    10. }
    11. ]
  • $project 将带有请求字段的文档传递到管道中的下一个阶段。指定的字段可以是输入文档中的现有字段,也可以是新计算的字段(只有 $project 里面声明了的字段才会输出到结果中)

  • $map 将表达式应用于数组中的每个项,并返回包含应用结果的数组
  • $map.input 解析为数组的表达式,这里示例中是 $departments,相当于引用集合中的 departments 字段,引用必须加 $ 前缀
  • $map.as 可选的。表示输入数组中每个单独元素的变量的名称。如果没有指定名称,变量名默认为 this
  • $map.in 应用于输入数组的每个元素的表达式。表达式使用as中指定的变量名单独引用每个元素(引用变量用 $$ 双美元符号)

    $set

    默认显示所有字段,再将 $set 中新声明的新字段追加到文档中
    1. {
    2. $lookup: <MongoDBAggregateLookupType>{
    3. from: "departments",
    4. localField: "managedDepartments.departmentId",
    5. foreignField: "_id",
    6. as: "departments",
    7. },
    8. },
    9. {
    10. $set: {
    11. id: "$_id",
    12. departments: {
    13. $map: {
    14. input: "$departments",
    15. as: "item",
    16. in: {
    17. id: "$$item._id",
    18. name: "$$item.name",
    19. },
    20. },
    21. },
    22. }
    23. }
    输出:
    1. [
    2. {
    3. "_id": "x",
    4. ...其余字段
    5. "departments": [
    6. {
    7. "id": "xx",
    8. "name: "bob"
    9. }
    10. ]
    11. }
    12. ]