代码编织梦想

上一篇我们介绍了MongoDB 聚合管道的文档筛选及分组统计:

        $match:文档过滤

        $group:文档分组,并介绍了分组中的常用操作:$addToSet,$avg,$sum,$min,$max等。

如果需要进一步了解可以参考:
MongoDB 聚合管道的文档筛选及分组统计https://blog.csdn.net/m1729339749/article/details/130034658这篇我们主要介绍使用聚合管道实现字段映射:

一、准备工作

初始化零食数据

db.goods.insertMany([
    { "_id": 1,  name: "薯片", size: "S", quantity: 10, price: 8, expirationTime: ISODate( "2023-08-08T00:00:00Z" ) },
    { "_id": 2,  name: "薯片", size: "L", quantity: 8, price: 12, expirationTime: ISODate( "2023-08-08T00:00:00Z" ) },
    { "_id": 3,  name: "牛肉干", size: "L", quantity: 5, price: 30, expirationTime: ISODate( "2023-10-10T00:00:00Z" ) },
    { "_id": 4,  name: "可口可乐", size: "S", quantity: 10, price: 3, expirationTime: ISODate( "2025-01-06T00:00:00Z" ) },
    { "_id": 5,  name: "可口可乐", size: "L", quantity: 6, price: 10, expirationTime: ISODate( "2025-01-06T00:00:00Z" ) },
    { "_id": 6,  name: "旺仔牛奶", size: "L", quantity: 10, price: 5, expirationTime: ISODate( "2023-08-10T00:00:00Z" )}
])

二、新增字段($addFields)

语法:{ $addFields: { <newField>: <expression>, ... } }

添加字段,从4.2开始后也可以使用$set增加字段

例子:在聚合数据中增加 comment 字段

db.goods.aggregate([
    {
        $addFields: { "comment": "我是新增加的" }
    }
])

此操作等效于:

db.goods.aggregate([
    {
        $set: { "comment": "我是新增加的" }
    }
])

聚合查询的结果如下:

{ "_id" : 1, "name" : "薯片", "size" : "S", "quantity" : 10, "price" : 8, "expirationTime" : ISODate("2023-08-08T00:00:00Z"), "comment" : "我是新增加的" }
{ "_id" : 2, "name" : "薯片", "size" : "L", "quantity" : 8, "price" : 12, "expirationTime" : ISODate("2023-08-08T00:00:00Z"), "comment" : "我是新增加的" }
{ "_id" : 3, "name" : "牛肉干", "size" : "L", "quantity" : 5, "price" : 30, "expirationTime" : ISODate("2023-10-10T00:00:00Z"), "comment" : "我是新增加的" }
{ "_id" : 4, "name" : "可口可乐", "size" : "S", "quantity" : 10, "price" : 3, "expirationTime" : ISODate("2025-01-06T00:00:00Z"), "comment" : "我是新增加的" }
{ "_id" : 5, "name" : "可口可乐", "size" : "L", "quantity" : 6, "price" : 10, "expirationTime" : ISODate("2025-01-06T00:00:00Z"), "comment" : "我是新增加的" }
{ "_id" : 6, "name" : "旺仔牛奶", "size" : "L", "quantity" : 10, "price" : 5, "expirationTime" : ISODate("2023-08-10T00:00:00Z"), "comment" : "我是新增加的" }

三、移除字段($unset)

语法:{ $unset: "<field>" }

        或 { $unset: [ "<field1>", "<field2>", ... ] }

移除字段,移除一个字段或者移除多个字段

例子:在聚合数据中移除  expirationTime字段

db.goods.aggregate([
    {    
        "$unset": "expirationTime"
    }
])

 聚合查询的结果如下:

{ "_id" : 1, "name" : "薯片", "size" : "S", "quantity" : 10, "price" : 8 }
{ "_id" : 2, "name" : "薯片", "size" : "L", "quantity" : 8, "price" : 12 }
{ "_id" : 3, "name" : "牛肉干", "size" : "L", "quantity" : 5, "price" : 30 }
{ "_id" : 4, "name" : "可口可乐", "size" : "S", "quantity" : 10, "price" : 3 }
{ "_id" : 5, "name" : "可口可乐", "size" : "L", "quantity" : 6, "price" : 10 }
{ "_id" : 6, "name" : "旺仔牛奶", "size" : "L", "quantity" : 10, "price" : 5 }

四、字段投影($project)

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

对文档中的字段进行投影操作,例如:保留哪些字段、移除哪些字段、添加新的字段、重置字段的值等。

specifications的定义如下:

<field>: 1 or true:代表的是保留某个字段

<field>: 0 or false:代表的是移除某个字段

<field>: <expression>:代表的是添加新的字段或者重置字段的值

例子:移除商品的生产日期、编号,添加商品的总价值,并把size的值替换成小包装、大包装

db.goods.aggregate([
    {
        $project: {
            "name": 1,
            "price": 1,
            "quantity": 1,
            "size": {
                $cond: {
                    if: { $eq: [ "S", "$size"] },
                    then: "小包装",
                    else: "大包装"
                }
            },
            "totalWorth": { $multiply: [ "$quantity", "$price" ] }
        }
    }
])

解释一下给出的聚合查询语句:

(1) 保留name、price、quantity三个字段;

(2) 重置size的值,如果字段size的值与"S"相等,返回“小包装”作为值,否则返回“大包装”作为值;里面的表达式运算符我们先做简单的介绍,后面会出一篇文章单独介绍;

(3) 新增总价值字段totalWorth,将数量与价格相乘的结果作为新增字段的值;里面的表达式运算符可以参考:

MongoDB 数据库操作汇总icon-default.png?t=N3I4https://blog.csdn.net/m1729339749/article/details/130086022中的聚合表达式运算符

下面我们看一下聚合查询的结果:

{ "_id" : 1, "name" : "薯片", "quantity" : 10, "price" : 8, "size" : "小包装", "totalWorth" : 80 }
{ "_id" : 2, "name" : "薯片", "quantity" : 8, "price" : 12, "size" : "大包装", "totalWorth" : 96 }
{ "_id" : 3, "name" : "牛肉干", "quantity" : 5, "price" : 30, "size" : "大包装", "totalWorth" : 150 }
{ "_id" : 4, "name" : "可口可乐", "quantity" : 10, "price" : 3, "size" : "小包装", "totalWorth" : 30 }
{ "_id" : 5, "name" : "可口可乐", "quantity" : 6, "price" : 10, "size" : "大包装", "totalWorth" : 60 }
{ "_id" : 6, "name" : "旺仔牛奶", "quantity" : 10, "price" : 5, "size" : "大包装", "totalWorth" : 50 }

可以看到里面的编号没有去除掉,原因是_id作为主键会自动保留,需要我们使用_id: 0 给强制去除掉

db.goods.aggregate([
    {
        $project: {
            "_id": 0,
            "name": 1,
            "price": 1,
            "quantity": 1,
            "size": {
                $cond: {
                    if: { $eq: [ "S", "$size"] },
                    then: "小包装",
                    else: "大包装"
                }
            },
            "totalWorth": { $multiply: [ "$quantity", "$price" ] }
        }
    }
])

再次执行聚合查询的结果如下:

{ "name" : "薯片", "quantity" : 10, "price" : 8, "size" : "小包装", "totalWorth" : 80 }
{ "name" : "薯片", "quantity" : 8, "price" : 12, "size" : "大包装", "totalWorth" : 96 }
{ "name" : "牛肉干", "quantity" : 5, "price" : 30, "size" : "大包装", "totalWorth" : 150 }
{ "name" : "可口可乐", "quantity" : 10, "price" : 3, "size" : "小包装", "totalWorth" : 30 }
{ "name" : "可口可乐", "quantity" : 6, "price" : 10, "size" : "大包装", "totalWorth" : 60 }
{ "name" : "旺仔牛奶", "quantity" : 10, "price" : 5, "size" : "大包装", "totalWorth" : 50 }

扩展:如何区分inclusion projection、exclusion projection

默认情况下是inclusion projection映射;

如果定义中出现的第一个非_id字段定义的映射为<field>: 0,则是exclusion projection映射;

如果定义中出现的第一个非_id字段定义的映射为<field>: 1,则是inclusion projection映射;

例子1:

db.goods.aggregate([
    {
        $project: {
            "_id": 0,
            "name": 1
        }
    }
])

如上面的例子,第一个非_id的字段定义的映射是"name": 1,则判断其是inclusion projection映射

例子2:

db.goods.aggregate([
    {
        $project: {
            "name": 0
        }
    }
])

如上面的例子,第一个非_id的字段定义的映射是"name": 0,则判断其是exclusion projection映射

扩展:inclusion projection中除_id:0外只能包含<field>: 1

           exclusion projection中除_id:1外只能包含<field>:0

 例子1:

db.goods.aggregate([
    {
        $project: { 
            "name": 1, 
            "size": 0 
        }
    }
])

执行上面的聚合查询会报错:

{
	"ok" : 0,
	"errmsg" : "Invalid $project :: caused by :: Cannot do exclusion on field size in inclusion projection",
	"code" : 31254,
	"codeName" : "Location31254"
}

分析原因:

第一个非_id的字段定义的映射是"name": 1,则判断其是inclusion projection映射,inclusion projection映射中除_id:0外只能包含<field>: 1,现在包含了"size": 0,则报了异常。

例子2:

db.goods.aggregate([
    {
        $project: { 
            "size": 0, 
            "name": 1
        }
    }
])

执行上面的聚合查询会报错:

{
	"ok" : 0,
	"errmsg" : "Invalid $project :: caused by :: Cannot do inclusion on field name in exclusion projection",
	"code" : 31253,
	"codeName" : "Location31253"
}

分析原因:

第一个非_id的字段定义的映射是"size": 0,则判断其是exclusion projection映射,exclusion projection映射中除_id:1外只能包含<field>: 0,现在包含了"name": 1,则报了异常。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m1729339749/article/details/130055110

mongodb 聚合操作之 $project 操作-爱代码爱编程

MongoDB 中的 $project 在 MongoDB 中可以使用 "$project" 来控制数据列的显示规则,可以执行的规则如下: 普通列({成员:1 | true}):表示要显示的内容"_id" 列({"_id":0 | false}):表示 "_id" 列是否显示条件过滤列({成员:表达式}):满足表达式之后的数据可以进行显示 首先,准备一

mangodb学习--聚合管道之$project-爱代码爱编程

Mangodb学习–聚合管道之$Project 文章目录 Mangodb学习--聚合管道之$Project$Project简介一、$project的进阶使用 $Project简介 是mangodb中的投

五、spring-data-mongodb中java字段映射注解-爱代码爱编程

Spring Data MongoDB通过注解可以很方便的将Java对象映射到MongoDB文档结构中。常用的字段映射注解主要有: @Document 注在实体类上,把ava类声明为mongodb的文档,​如果

mongo java 根据if条件addfields-爱代码爱编程

mongo脚本: db.collection1.aggregate([ { $addFields: { newColumn:{ $cond: { if: { $eq:["$query1", 1], $eq:["$query2", 2]},

mongodb聚合操作_mongodb $addfields-爱代码爱编程

目录 聚合操作 聚合管道操作符  管道优化 聚合操作 插入一匹数据: db.orders.insertMany( [ {  zip:"000001",  phone:"13101010101",  name:"xiaowang",  status:"created",  shippingFee:10,  orderLines:[      {p

深入探索mongodb集群模式:从高可用复制集-爱代码爱编程

MongoDB复制集概述 MongoDB复制集主要用于实现服务的高可用性,与Redis中的哨兵模式相似。它的核心作用是数据的备份和故障转移。 复制集的主要功能 数据复制:数据写入主节点(Primary)时,自动复制到一个或多个副本节点(Secondary)。故障恢复:主节点失效时,自动从副本节点中选举出新的主节点。 复制集的附加作用 数据分发:将

python安装mongodb与运算符优先级-爱代码爱编程

python安装MongoDB  MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON)。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 PyMongo 驱动来连接。 pip 安装 pip 是一个通用的 Python 包管理工具,提供了对 Pyt

mongodb聚合:$out-爱代码爱编程

$out阶段将聚合管道产生的文档写入到指定的集合,从MongoDB4.4开始,支持指定数据库。$out阶段必须放在聚合管道的最后,支持聚合结果任意大小的数据集。 警告: 如果指定的集合已经存在则会被替换。 语法 用法

启动mongodb失败-爱代码爱编程

Failed to start mongod.service:until not  found 解决办法: 1创建配置文件:     sudo nano [lc1] /etc/systemd/system/mongodb.service 2.在里面追加文本:    [Unit]    Description=High-performance,

mongodb主从仲裁模式安装-爱代码爱编程

MongoDB主从仲裁模式安装 环境介绍 操作系统 : CentOS release 6.8 (Final) Master IP : 10.4.19.83 Arbiter IP : 10.104.27.126 Sl