一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
前言
本文章内容重点是在操作符的使用上,如果要更好的了解具体的概念请移步到 mongodb官网文档
$project
假设有一个作品表
import { ObjectID } from "mongodb";
async function getArtworkByArtworkId(artworkId: string) {
const res = await artworkRepo.aggregate([
{ $match: { _id: { $eq: new ObjectID(artworkId) } } },
]).toArray();
}
// 查询结果
[
{
_id: "",
name: "",
imgUrl: "",
desc: "",
authorId: "",
status: "",
createTime: "",
}
]
我现在不想查出那么多字段啊,我只想要这个作品的id和图片,一个方法是拿到结果后取出想要的数据再返回给前端。第二个方法就是,让查询语句来帮我做这件事。如何做呢?这个时候就用到 $project
这个操作符了。
// 简单介绍:
$project: {
[字段名]: 1 or true || 0 or false
}
/**
* value 为 1 or true,表示取出该字段
* value 为 0 or false,则表示排除该字段
*/
// 例如:
$project: {
_id: 1,
imgUrl: 1
}
结果就是只取出 { _id: "", imgUrl: "" }
$project: {
createTime: 0
}
结果就是除了createTime,其他的字段都查出来
应用到实际例子中
await artworkRepo.aggregate([
{ $match: { _id: { $eq: new ObjectID(artworkId) } } },
{
$project: {
_id: 1,
imgUrl: 1
}
}
]).toArray()
$group
$group
会按指定的 _id
表达式对输入文档进行分组,其实看它的名字就知道是分组用的。我看下面的这个例子,查了三个表,输出的字段是非常多的,我不用这么多字段啊,而且我只想要下面这种结构,不想要嵌套有数组。(我这个例子可能不太合适,读者请自行辨别)
{
userId: "",
artworkId: "",
commentId: ""
}
// 不想要其他字段
import { ObjectID } from "mongodb";
async function getUserArtwork(userId: string) {
// 1.user表
const res = await userRepo.aggregate([
{
$match: { _id: { $eq: new ObjectID(userId) } }
},
{
$addFields: { _userId: "$_id" },
},
// 2.作品表
{
$lookup: {
from: "artworks",
let: { userId: "$_id" }, // 定义一个变量 ( users表中的_id )
pipeline: [
{
$addFields: {
_artworkId: "$_id", // 作品表中的作品ID
},
},
{
$match: {
$expr: {
$eq: ["$authorId", "$$userId"], // authorId == userId
},
isShow: true
},
},
// 3.评论表
{
$lookup: {
from: "artwork_comment",
localField: "_artworkId", // 作品表中的作品ID
foreignField: "artworkId",
as: "comments",
},
},
],
as: "artworks", // 起一个别名
},
},
{
$unwind: {
path: "$artworks", // 这个变量 就是上面的 as: "artworks"
// 如果不设置为true允许为空,那么如果为空,就不会输出这一条记录
preserveNullAndEmptyArrays: true,
},
},
{
// 这里访问的 $artworks,是 $unwind 定义的
$group: {
// 这个_id 是 必须的,因为需要用到这个_id来分组
_id: "$_userId", // 这个是 $addFields 一开始我定义的 _userId
userId: "$_userId",
artworkId: { $last: { "$artworks._id" } }
commentId: { $last: { $last: { "$artworks.comments._id" } } }
},
},
]).toArray();
}
$unwind
$unwind
操作符的用法最好是看管方文档,这里我就不展开了。
好了,上面就得到了我想要的数据结构啦,主要是 $unwind
和 $group
操作符的运用。
写在最后
至此,文章就分享完毕了,欢迎在评论区交流。
如果文章对你有所帮助,不要忘了点上宝贵的一赞!
听说点赞的人运气都不差,相信来年第一个升职加薪的一定是你~