MongoDB视图的增删改查基本操作

502 阅读2分钟

一、视图

MongoDB视图是一个可查询的对象,它的内容由其他集合或视图上的聚合管道定义。 MongoDB不会将 视图内容持久化到磁盘。 当客户端查询视图时,视图的内容按需计算。 MongoDB可以要求客户端具有 查询视图的权限。 MongoDB不支持对视图进行写操作。

作用:

  • 数据抽象
  • 保护敏感数据的一种方法
  • 将敏感数据投影到视图之外
  • 只读
  • 结合基于角色的授权,可按角色访问信息

为了便于演示视图,首先先准备一些测试数据 数据准备

var orders = new Array();
var shipping = new Array();
var addresses = ["广西省玉林市", "湖南省岳阳市", "湖北省荆州市", "甘肃省兰州市", "吉林省松原市", "江西省景德镇", "辽宁省沈阳市", "福建省厦门市", "广东省广州市", "北京市朝阳区"];
for (var i = 10000; i < 20000; i++) {
    var orderNo = i + Math.random().toString().substr(2, 5);
    orders[i] = { orderNo: orderNo, userId: i, price: Math.round(Math.random() *10000) / 100, qty: Math.floor(Math.random() * 10) + 1, orderTime: new Date(new Date().setSeconds(Math.floor(Math.random() * 10000)))
    };
    var address = addresses[Math.floor(Math.random() * 10)];
    shipping[i] = { orderNo: orderNo, address: address, recipienter: "Wilson",province: address.substr(0, 3), city: address.substr(3, 3) }
}
db.order.insert(orders);
db.shipping.insert(shipping);

如上代码可以使用mongo登录之后直接执行,也可以将以上代码放到mongo的根目录,然后执行load(aa.js)

查看创建好的表show tables

image.png

1-1、创建视图

使用关键方法:createView

基本语法格式

db.createView(
    "<viewName>",
    "<source>",
    [<pipeline>],
    {
        "collation" : { <collation> }
    }
)
  • viewName : 必须,视图名称
  • source : 必须,数据源,集合/视图
  • [] : 可选,一组管道
  • collation 可选,排序规则

1-1-1、单个集合创建视图

假设现在查看当天最高的10笔订单视图,例如需要实时显示金额最高的订单

实现思路:查询当天订单、安装金额大小进行倒序排列,并取10条,这个就用到了管道操作,用到的核心管道如下:

$match:用于查询当天的订单
$sort: 用于对金额排序
$limit:用于获取10条数据

最终创建视图命令

db.createView(
    "orderInfo", //视图名称
    "order", //数据源
    [
//筛选符合条件的订单,大于当天,这里要注意时区
        { $match: { "orderTime": { $gte: ISODate("2022-12-08T00:00:00.000Z") } }},
//按金额倒序
        { $sort: { "price": -1 } },
//限制10个文档
        { $limit: 10 },
//选择要显示的字段
//0: 排除字段,若字段上使用(_id除外),就不能有其他包含字段
//1: 包含字段
        { $project: { _id: 0, orderNo: 1, price: 1, orderTime: 1 } }
    ]
)

创建成功后,可以直接使用查询数据:db.orderInfo.find()

image.png

1-1-2、多个集合创建视图

跟单个是集合是一样,只是多了$lookup连接操作符,视图根据管道最终结果显示,所以可以关联多个集合

比如查询订单及订单的地址信息。这样就需要将order和shipping两个表通过$lookup进行关联。

db.orderDetail.drop()
db.createView(
"orderDetail",
"order",
[
{ $lookup: { from: "shipping", localField: "orderNo", foreignField:
"orderNo", as: "shipping" } },
{ $project: { "orderNo": 1, "price": 1, "shipping.address": 1 } }
]
)

创建 image.png

使用

image.png

1-2、修改视图

使用关键方法:runCommand()

通过如下脚本,可以发现修改除了使用runCommand之外,同时视图名称需要指定:colMod为key,对应的表名称需要指定:viewOn为key,同时管道需要指定pipeline为key

如下就是修改之前的视图,将qty字段显示出来

db.runCommand({
collMod: "orderInfo",
viewOn: "order",
pipeline: [
{ $match: { "orderTime": { $gte: ISODate("2020-04-13T16:00:00.000Z") } }
},
{ $sort: { "price": -1 } },
{ $limit: 10 },
//增加qty
{ $project: { _id: 0, orderNo: 1, price: 1, qty: 1, orderTime: 1 } }
]
})

如下,针对创建主要需要改动如下关键字,需要注意多了开头结尾的{},执行之后查询结果,多了qty字段

image.png

1-3、删除视图

和删除表命令一样,都使用drop命令

db.视图名称.drop()