MongoDB聚合:$project

$project聚合阶段可将输入文档根据请求的字段输出到管道的下个阶段,输出的字段可以是输入文档中的字段,也可以是新的计算字段。

语法

{ $project: { <specification(s)> } }

$project聚合接受一个文档参数,可以指定包含的字段,抑制_id字段,添加新的字段以及重置已有字段的值等。亦或者,也可以指定排除的字段。

$project的参数字段可以是下面的形式:

参数字段形式描述
<字段>:<1或true>指定包含的字段,非0整数也被视为true
_id:<0或false>指定抑制_id字段,也就是_id字段不会被传递到下个阶段。也可以使用REMOVE变量和条件排除字段
<字段>:<表达式>添加一个新字段或者重置已有字段的值。如果表达式的值为$$REMOVE,则字段被排除
<字段>:<0或false>排除一个指定的字段。可以使用REMOVE变量和条件排除字段,如果排除_id以外的字段,则不能同时使用其他形式,但是REMOVE变量条件排除字段除外

使用

包含现有字段

  • _id字段默认输出,如果要包含其他字段,必须明确的指定。
  • 如果指定要包含的字段在输入文档中不存在,$project将忽略该字段,输出文档中也不会包含该字段。

抑制_id字段

缺省情况下输出文档包含_id字段,如果不想让_id字段出现在输出文档中必须显示的指定抑制_id字段。

排除字段

如果指定了排除字段,没有被指定的字段默认输出到下个阶段。

{ $project: { "<field1>": 0, "<field2>": 0, ... } } // 将返回所有没有被指定的字段

如果指定了排除_id字段以外的其他字段,则不能再使用其他形式来指定字段,也就是说这种情况下不能再指定包含其他字段,也不能指定新的字段或重置已有字段。但可以使用REMOVE变量条件排除字段。

条件排除字段

可以使用REMOVE变量根据表达式条件抑制一个字段。

添加字段或重置已有字段

**注意:**也可以使用$addFields来为文档添加字段。

要添加一个字段或重置已有字段的值,可以指定字段名并使用表达式指定值

字面量值

要将字段值直接设置为数字或布尔字面量,而不是将字段设置为解析为字面量的表达式,可使用$literal操作符。否则,$project将把数字或布尔字面量视为包含或排除字段的标志。

修改字段名

通过指定一个新字段并将其值设置为现有字段的字段路径,可以重命名一个字段。

新增数组字段

$project阶段支持使用方括号[]直接创建新的数组字段,如果指定的数组字段在文档中不存在,则操作会将空值替换为该字段的值。

内嵌文档字段

当重塑、添加或重置内嵌文档的字段时,可以使用点号或嵌套字段:

点号形式:

"contact.address.country": <1 or 0 or 表达式>

嵌套字段形式:

contact: { address: { country: <1 or 0 or 表达式> } }

当使用嵌套字段时,不能在嵌套文档内部使用点号指定字段,如下面的就是错误的方式:

contact: { "address.country": <1 or 0 or 表达式> }
内嵌文档字段的路径冲突错误

不能在同一投影中同时指定嵌入文档和嵌入文档中的字段。下面的$project阶段有路径冲突错误,因为试图同时重塑内嵌文档contactcontact.address.country字段:

{ $project: { contact: 1, "contact.address.country": 1 } }

这种错误与父文档和内嵌字段的顺序无关,下面的$project是同样的错误:

{ $project: { "contact.address.country": 1, contact: 1 } }
$project阶段的位置

当使用$project截断式,通常情况下它应该放在管道的最后阶段,用它来指定返回给客户端的字段。

没有必要为了减少传递到后续管道的字段数量而把$project阶段放在管道的开始或中间,这也不太可能提高性能,数据库会自动执行这种优化。

限制

  • $project制定一个空文档会返回错误。
  • $project阶段中不能使用数组下标。

举例

输出文档中包含指定字段

有一个book集合包含下面的文档:

{"_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5
}

经过下面的$project阶段处理后,输出文档中只包含_idtitleauthor字段。

db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )

聚合操作结果:

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

在输出文档中抑制_id字段

缺省情况下总是包含_id字段,如果要在输出文档中排除_id字段,可以在参数中给_id指定0

books集合中有下面的文档:

{"_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5
}

经过下面的$project聚合阶段后,_id字段被抑制,输出文档中只有titleauthor字段:

db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )

聚合后的结果:

{ "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

排除输出文档字段

books集合有下面文档:

{"_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5,"lastModified": "2016-07-28"
}

下面的$peoject阶段排除掉了lastModified字段:

db.books.aggregate( [ { $project : { "lastModified": 0 } } ] )

结果输出:

  "_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5

排除内嵌字段

books集合有下面文档:

{"_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5,"lastModified": "2016-07-28"
}

下面的$project阶段排除了输出文档中author.firstlastModified字段:

db.books.aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )

或者,也可以使用字段嵌套来排除字段:

db.bookmarks.aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )

这两种方式的结果是等价的:

{"_id" : 1,"title" : "abc123","isbn" : "0001122223334","author" : {"last" : "zzz"},"copies" : 5,
}

用条件排除字段

可以在聚合表达式中使用REMOVE变量有条件的抑制一个字段。

books集合中有下面的文档:

{"_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5,"lastModified": "2016-07-28"
}
{"_id" : 2,"title": "Baked Goods","isbn": "9999999999999","author": { "last": "xyz", "first": "abc", "middle": "" },"copies": 2,"lastModified": "2017-07-21"
}
{"_id" : 3,"title": "Ice Cream Cakes","isbn": "8888888888888","author": { "last": "xyz", "first": "abc", "middle": "mmm" },"copies": 5,"lastModified": "2017-07-22"
}

下面的$proejct阶段使用RREMOVE变量排除author.middle值为""的字段:

db.books.aggregate( [{$project: {title: 1,"author.first": 1,"author.last" : 1,"author.middle": {$cond: {if: { $eq: [ "", "$author.middle" ] },then: "$$REMOVE",else: "$author.middle"}}}}
] )

聚合后的结果:

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
{ "_id" : 2, "title" : "Baked Goods", "author" : { "last" : "xyz", "first" : "abc" } }
{ "_id" : 3, "title" : "Ice Cream Cakes", "author" : { "last" : "xyz", "first" : "abc", "middle" : "mmm" } }

包含内嵌文档的指定字段

bookmarks有下面的文档:

{ "_id": 1, "user": "1234", "stop": { "title": "book1", "author": "xyz", "page": 32 } }
{ "_id": 2, "user": "7890", "stop": [ { "title": "book2", "author": "abc", "page": 5 }, { "title": "book3", "author": "ijk", "page": 100 } ] }

如果要输出文档中只包含内嵌文档stoptitle字段,可以使用点号或嵌套字段来指定:

用点号指定:

db.bookmarks.aggregate( [ { $project: { "stop.title": 1 } } ] )

用嵌套字段指定:

db.bookmarks.aggregate( [ { $project: { stop: { title: 1 } } } ] )

两种方式是等价的,输出文档如下:

{ "_id" : 1, "stop" : { "title" : "book1" } }
{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] }

包含计算字段

books集合中有下面的文档:

{"_id" : 1,"title": "abc123","isbn": "0001122223334","author": { "last": "zzz", "first": "aaa" },"copies": 5
}

下面的$project聚合阶段为输出文档添加isbnlastcopiesSold

db.books.aggregate([{$project: {title: 1,isbn: {prefix: { $substr: [ "$isbn", 0, 3 ] },group: { $substr: [ "$isbn", 3, 2 ] },publisher: { $substr: [ "$isbn", 5, 4 ] },title: { $substr: [ "$isbn", 9, 3 ] },checkDigit: { $substr: [ "$isbn", 12, 1] }},lastName: "$author.last",copiesSold: "$copies"}}]
)

操作返回下面的结果:

{"_id" : 1,"title" : "abc123","isbn" : {"prefix" : "000","group" : "11","publisher" : "2222","title" : "333","checkDigit" : "4"},"lastName" : "zzz","copiesSold" : 5
}

添加数组字段

一个coll集合有下面的文档:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 }

下面的操作将字段xy重塑为myArray字段的数组元素:

db.coll.aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] )

操作返回下面的结果:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] }

不支持数组下标

不能在$project阶段使用数组下标,请看下面的例子:

创建pizzas集合:

db.pizzas.insert( [{ _id: 0, name: [ 'Pepperoni' ] },
] )

下面的例子返回披萨:

db.pizzas.aggregate( [{ $project: { x: '$name', _id: 0 } },
] )

输出结果中包含了披萨:

[ { "x": [ "Pepperoni" ] } ]

下面的例子使用数组下标{$name.0}试图返回一个披萨:

db.pizzas.aggregate( [{ $project: { x: '$name.0', _id: 0 } },
] )

但是结果中并没有披萨返回:

[ { "x": [] } ]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/683062.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java安全 CC链6分析

CC链6分析 前言CC链分析核心transform链Lazymap类TiedMapEntry类HashMap方法 最终exp 前言 CC链6不受jdk版本与cs版本的影响&#xff0c;在Java安全中最为通用&#xff0c;并且非常简洁&#xff0c;非常有学习的必要&#xff0c;建议在学习CC链6之前先学习一下 URLDNS链 和 CC…

创建良好班风的重要性和意义

为什么有的班级总是充满活力&#xff0c;学生们团结友爱、学习热情高涨&#xff0c;而有的班级却显得沉闷&#xff0c;学生们缺乏动力&#xff0c;对学习毫无兴趣&#xff1f;其实&#xff0c;这背后的关键就在于班风的建设。 班风&#xff0c;简单说&#xff0c;就是一个班级…

【机器学习案例2】使用 plaidML在 macOS利用GPU进行机器学习【含源码】

想要在 Mac 的集成 AMD GPU 或外部显卡上训练机器学习模型? PlaidML 就是您的最佳选择。 任何尝试过在 macOS 上使用 TensorFlow 训练神经网络的人都知道这个过程有点糟糕。 TensorFlow 只能利用 Mac 上的 CPU,因为 GPU 加速训练需要 Nvidia 芯片组。大多数大型模型在 CPU 上…

IDEA在package下右键,没有new选项

正常情况下如下图&#xff0c;我们在文件夹上右键&#xff0c;是会出现New选项的。 但是今天我尝试将" add frameworks support"添加到右键时&#xff0c;竟然把New都删除了。如下图 搜遍全网&#xff0c;结果搜到的都是为什么在package或者文件夹上右键出现的Ne…

Linux网络操作系统期末系统复习题

一、填空题 1. GUN 的含义是 一个自由的操作系统。 2. Linux 一般有 3 个主要部分&#xff1a; 内核、命令解释层 、实用工具 。 3. 目前被称为纯种的UNIX指的就是System V以及BSD这两套操作系统。 4. Linux是基于Copyleft的软件模式进行发布的&#xff0c;它是GNU项目…

springboot185基于vue.js的客户关系管理系统(crm)的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

【Linux技术宝典】深入理解Linux基本指令:命令行新手指南

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅Linux技术宝典 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 一、Linux下基本指令1. ls 指令2. pwd指令3. clear指令4. cd指令什么是家目录&#xf…

基于AI Agent探讨:安全领域下的AI应用范式

先说观点&#xff1a;关于AI应用&#xff0c;通常都会聊准召。但在安全等模糊标准的场景下&#xff0c;事实上不存在准召的定义。因此&#xff0c;AI的目标应该是尽可能的“像人”。而想要评价有多“像人”&#xff0c;就先需要将人的工作数字化。而AI Agent是能够将数字化、自…

java基础实现的图书管理系统

文章目录 项目介绍项目功能代码讲解如何实现不同用户之间的操作权限不同 项目介绍 该项目是用的是javase的一些知识包括了类和对象封装&#xff0c;继承多态等面向对象的三大特性。主要是为了让我们能够更好的使用之前学到的知识。 接下来给大家讲解一下这个项目的一个特点。首…

面试计算机网络框架八股文十问十答第六期

面试计算机网络框架八股文十问十答第六期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;DNS 协议是什么 D…

31.File文件

File文件 1. 概述2. 构造方法2.1 方法2.2 代码示例 3. 成员方法3.1 判断、获取的方法3.1.1 方法3.1.2 代码示例 3.2 创建、删除的方法3.2.1 方法3.2.2 代码示例 3.3 获取、遍历的方法3.3.1 重点方法3.3.1.1 方法3.3.1.2 代码示例 3.3.2 所有方法3.3.2.1 方法3.3.2.2 代码示例 4…

《Docker快速入门:从0到1构建你的第一个容器!》

《Docker快速入门&#xff1a;从0到1构建你的第一个容器&#xff01;》 前言 欢迎来到Docker的世界&#xff0c;一个让应用程序打包、部署和运行更加容易的神奇平台。Docker改变了我们对于应用开发和分发的看法&#xff0c;它通过容器技术让软件的携带和运行变得前所未有的轻…

OpenGL-ES 学习(4)---- OpenGL-ES 坐标体系

坐标体系 我们知道 OpenGL -ES 坐标系中每个顶点的 x&#xff0c;y&#xff0c;z 坐标都应该在 -1.0 到 1.0 之间&#xff0c;超出这个坐标范围的顶点都将不可见。 将一个物体&#xff08;图像&#xff09;渲染到屏幕上&#xff0c;通常经过将物体坐标转换为标准化设备坐标&am…

蓝牙BLE学习-GAP

1.概述 GAP层&#xff08;Generic access profile-通用访问配置文件&#xff09;。GAP是对LL层payload&#xff08;有效数据包&#xff09;如何进行解析的两种方式的一种&#xff0c;而且也是最简单的一种。GAP简单的对LL payload进行一些规范和定义&#xff0c;因此GAP能实现的…

(三十八)大数据实战——Atlas元数据管理平台的部署安装

前言 Apache Atlas 是一个开源的数据治理和元数据管理平台&#xff0c;旨在帮助组织有效管理和利用其数据资产。为组织提供开放式元数据管理和治理功能 &#xff0c;用以构建其数据资产目录&#xff0c;对这些资产进行分类和管理&#xff0c;形成数据字典 。并为数据分析师和数…

容器高级知识:Kubernetes Pod 适配器模式详解

Kubernetes Pod 适配器(Adapter)模式详解 Kubernetes Pod 适配器模式是侧车&#xff08;Sidecar&#xff09;模式的一个特例&#xff0c;其中使用专用的 适配器容器 在主应用程序容器和其他服务或客户端之间 翻译 数据或信号。它充当桥梁&#xff0c;调整通信格式或协议以实现…

深度学习之反向传播算法

反向传播算法 数学公式算法代码结果 算法中一些函数的区别 数学公式 算法代码 这里用反向传播算法&#xff0c;计算 y w * x模型 import numpy as np import matplotlib.pyplot as ply#反向传播算法&#xff0c;需要使用pytorch框架&#xff0c; #这里导入pytorch框架&#xf…

MySQL 基础知识(四)之表操作

目录 1 约束 2 查看已有表 3 创建表 4 查看表结构 5 修改表 6 删除表 1 约束 主键约束 primary key&#xff1a;唯一&#xff0c;标识表中的一行数据&#xff0c;此列的值不可重复&#xff0c;且不能为 NULL&#xff0c;此外&#xff0c;可以多个列组成主键唯一约束 uniq…

Phobos捆绑某数控软件AdobeIPCBroker组件定向勒索

前言 Phobos勒索病毒最早于2019年被首次发现并开始流行起来&#xff0c;该勒索病毒的勒索提示信息特征与CrySiS(Dharma)勒索病毒非常相似&#xff0c;但是两款勒索病毒的代码特征却是完全不一样&#xff0c;近日笔者在逛某开源恶意软件沙箱的时候发现了一款Phobos勒索病毒捆绑…

Windows编程环境配置!

喜欢的话麻烦大家多点点关注&#xff0c;谢谢&#xff01; 原文地址&#xff1a;Windows编程环境配置&#xff01; - Pleasure的博客 下面是正文内容&#xff1a; 前言 近期闲来无事&#xff0c;就想着把Windows系统中的环境给完善整理一下。方便后续码字时的不时之需。 正文…