Loading

mongodb 复杂查询

记录一下工作中用到的 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"
      }
     ]
  }
]
posted @ 2022-03-01 17:42  myEsn2E9  阅读(192)  评论(0编辑  收藏  举报