MongoDB 5.x安装使用, aggregation管道与sql语法参照

1. 安装

使用 docker-compose 参考: https://hub.docker.com/_/mongo

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: example
      ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/

2. 基本使用

  1. 切换数据库
show dbs # 查看数据库
show collections # 查看集合
use test # 切换数据库, 没有的话,在创建集合时,会自动创建
  1. 创建集合
db.createCollection('t_user')
  1. 添加数据
# 单条插入
db.t_user.insert(
    { "name": "hello", "age": 22, "sex": "男" }
)

# 批量插入
db.t_user.insertMany([
    { "name": "hello1", "age": 23, "sex": "男" },
	{ "name": "hello2", "age": 24, "sex": "男" },
	{ "name": "hello3", "age": 25, "sex": "男" }
])

3. 管道查询 aggregation

Sql语法中

  • 基本查询where: <>=!/and/ or/in/not in/like
  • 关联查询join: left join/right join/inner join
  • 字段排序order: asc/desc

在MongoDB 5.x的管道中都可以实现类似的功能

3.1 基本运算

参照表:

SQL where MongoDB $match
= $eq
!= $ne
> $gt
>= $gte
< $lt
<= $lte

sql

select * from t_user where age=23;

mongo

db.t_user.aggregate([{
$match: {
   $expr: {
        $eq: ["$age", 23]
   }
}
}])

或者

db.t_user.aggregate([{
$match: {
   age: { $eq: 23 }
}
}])

3.2 模糊查询 like

在mongo中使用$regex正则

sql

select * from t_user where name like '%hello%';

mongo

db.t_user.aggregate([{
$match: {
   name: {
    $regex: "hello",
    $options:'i'
   }
}
}])

3.3 列表查询 in

在mongo中使用$in

sql

select * from t_user where name in ('hello', 'hello1');

mongo

db.t_user.aggregate([{
$match: {
   name: {
    $in: ["hello", "hello1"]
   }
}
}])

3.4 逻辑取反 $not

在mongo中使用$not对查询逻辑进行取反. 比如配合$in实现not in的效果, 也可以使用$nin

sql

select * from t_user where name not in ('hello', 'hello1');

mongo

db.t_user.aggregate([{
$match: {
   name: {
    $not: { $in: ["hello", "hello1"] }
   }
}
}])

3.5 条件and

在mongo中使用$and

sql

select * from t_user where name='hello' and age=23;

mongo

# 方式1
db.t_user.aggregate([{
$match: {
   name: { $eq: "hello" },
   age: { $eq: 23 }
}
}])

# 方式2
db.t_user.aggregate([{
$match: {
    $and: [
        {name: { $eq: "hello" }},
        {age: { $eq: 23 }}
    ]
}
}])

3.6 条件or

在mongo中使用$or

sql

select * from t_user where name='hello' or age=24;

mongo

db.t_user.aggregate([{
$match: {
    $or: [
        {name: { $eq: "hello" }},
        {age: { $eq: 24 }}
    ]
}
}])

3.7 条件and和or嵌套使用

sql

select * from t_user where name='hello' and (age=23 or sex='男');

mongo

db.t_user.aggregate([{
$match: {
    $and: [
        {name: { $eq: "hello" }},
        {$or:[
            {age: { $eq: 23 }},
            {sex: { $eq: "男" }}
        ]}
    ]
}
}])

3.8 分组group

在mongo中使用$group, 分组字段使用_id,形式:

_id: {name: "$name", age: "$age"}
SQL mongo
count $count
sum $sum
max $max
min $min
avg $avg

sql

select count(*) as count, sum(age) as ageSum, max(age) as ageMax, min(age) as ageMin, avg(age) as ageAvg from t_user group by name;

mongo

db.t_user.aggregate([{
$group: {
    _id: {name: "$name"},
    count: {$count: {}},
    ageSum: {$sum: "$age"},
    ageMax: {$max: "$age"},
    ageMin: {$min: "$age"},
    ageAvg: {$avg: "$age"}
}
}])

3.9 排序sort

在mongo中使用$sort

  • 1 正序 asc
  • -1 倒序 desc

sql

select * from t_user order by name asc, age desc;

mongo

db.t_user.aggregate([{
$sort : { name: 1, age : -1}
}])

3.10 表链接 join

在mongo中使用$lookup, 在mongo中只存在左连接类似left join功能, 如果想使用right join就只能调换两个集合的顺序;

结合$unwind指令, 通过preserveNullAndEmptyArrays属性实现inner join的效果.

语法示例说明:

$lookup: {
    from: 't_info', # 被连接的集合
    let: {info_name: "$name"}, # 连接字段需要先指定引用变量的名称,才能在管道中被使用
     pipeline: [{ # 通过管道实现连接功能
        $match: { # 通过$match 实现连接条on的功能
           $expr: {
              $and: [ ## 通过 $$ 引用let定义的变量
                  { $eq: [ "$$info_name", "$name" ] }
              ]
           }
        }
     }],
    as: 't_info' # 指定被连接的文档在管道中的名字
}

创建t_info集合

db.createCollection('t_info')

db.t_info.insertMany([
    { "name": "hello", "age": 23, "addr": "银河" }
])

sql

select * from t_user u left join t_info t on u.name=t.name;

mongo

db.t_user.aggregate([{
    $lookup: {
        from: 't_info',
        let: {info_name: "$name"},
         pipeline: [{
            $match: {
               $expr: {
                  $and: [
                      { $eq: [ "$$info_name", "$name" ] }
                  ]
               }
            }
         }],
        as: 't_info'
    }}
    ,{$unwind:{ path: '$t_info', preserveNullAndEmptyArrays: true }}
    ,{$project: {name:1, age:1, addr:"$t_info.addr"}}
])

preserveNullAndEmptyArrays: false (默认) inner join

posted @ 2022-02-19 12:32  林宇风  阅读(162)  评论(0编辑  收藏  举报