社区首页 >问答首页 >基于嵌套数组条件的mongoDB updateMany

基于嵌套数组条件的mongoDB updateMany
EN

Stack Overflow用户
提问于 2020-02-10 03:59:27
回答 1查看 582关注 0票数 1

我在users集合中有以下结构:

代码语言:javascript
代码运行次数:0
复制
[
  { "name": "Ivan", 
    "payments": [
      {"date": new Date("2019-01-01"), "details": [{"payment_system": "A", "spent": 95}, 
                                                   {"payment_system": "B", "spent": 123}]},
      {"date": new Date("2019-01-03"), "details": [{"payment_system": "A", "spent": 12}, 
                                                   {"payment_system": "B", "spent": 11}]}]},
  { "name": "Mark", 
    "payments": [
      {"date": new Date("2019-01-01"), "details": [{"payment_system": "D", "spent": 456}, 
                                                   {"payment_system": "B", "spent": 123}]}, 
      {"date": new Date("2019-01-02"), "details": [{"payment_system": "A", "spent": 98}, 
                                                   {"payment_system": "C", "spent": 4}]}]}
]

有没有办法在特定的支付系统中,在特定的日期范围内,向那些花费超过100美元的用户添加一个字段?我尝试过updateMany,但是不知道如何过滤基于payment_system字段的“细节”数组元素。

对于payment_system IN ("A", "C"), date >= "2019-01-02", spent_total >= 100,更新应该返回

代码语言:javascript
代码运行次数:0
复制
[
  { "name": "Ivan", ...},
  { "name": "Mark", "filter_passed": true, ... }
]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-10 04:35:06

这个这个:

代码语言:javascript
代码运行次数:0
复制
db.collection.aggregate([
   {
      $set: {
         payments: {
            $filter: {
               input: "$payments",
               cond: { $gte: ["$$this.date", new Date("2019-01-02")] }
            }
         }
      }
   },
   {
      $set: {
         spent_total: {
            $reduce: {
               input: "$payments.details.spent",
               initialValue: [],
               in: { $concatArrays: ["$$value", "$$this"] }
            }
         }
      }
   },
   { $set: { spent_total: { $sum: "$spent_total" } } },
   { $match: { "spent_total": { $gte: 100 } } }
])

Mongo 游乐场

更新:

payment_system的过滤器要长一点。你必须要$unwind$group

代码语言:javascript
代码运行次数:0
复制
db.collection.aggregate([
   {
      $set: {
         payments: {
            $filter: {
               input: "$payments",
               cond: { $gte: ["$$this.date", new Date("2019-01-02")] }
            }
         }
      }
   },
   { $unwind: "$payments" },
   {
      $set: {
         "payments.details": {
            $filter: {
               input: "$payments.details",
               cond: { $in: ["$$this.payment_system", ["A", "C"]] }
            },
         },
      }
   },
   {
      $group: {
         _id: { _id: "$_id", name: "$name", },
         payments: { $push: "$payments" }
      }
   },
   {
      $set: {
         spent_total: {
            $reduce: {
               input: "$payments.details.spent",
               initialValue: [],
               in: { $concatArrays: ["$$value", "$$this"] }
            }
         }
      }
   },
   { $set: { spent_total: { $sum: "$spent_total" } } },
   { $match: { "spent_total": { $gte: 100 } } },
   { // just some cosmetic
      $project: {
         _id: "$_id._id",
         name: "$_id.name",
         payments: 1
      }
   }
])

不能像db.collection.updateMany({}, [<the aggregation pipeline from above>])一样更新集合,因为它包含$unwind$group。但是,您可以使$lookup$out将整个结果保存到新集合中。

如果您需要对每个payment_system分别进行汇总,那么请尝试:

代码语言:javascript
代码运行次数:0
复制
db.collection.aggregate([
   {
      $set: {
         payments: {
            $filter: {
               input: "$payments",
               cond: { $gte: ["$$this.date", new Date("2019-01-01")] }
            }
         }
      }
   },
   { $unwind: "$payments" },
   {
      $set: {
         "payments.details": {
            $filter: {
               input: "$payments.details",
               cond: { $in: ["$$this.payment_system", ["A", "B","C"]] }
            },
         },
      }
   },
   { $unwind: "$payments.details" },
   {
      $group: {
         _id: {
            _id: "$_id",
            name: "$name",
            payments: "$payments.details.payment_system"
         },
         spent_total: { $sum: "$payments.details.spent" }
      }
   },
   { $match: { "spent_total": { $gte: 100 } } },
   {
      $project: {
         _id: "$_id._id",
         name: "$_id.name",
         payments: "$_id.payments",
         spent_total: 1
      }
   }   
])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60149986

复制
相关文章
应用容器云:接过Java EE的枪
主要大纲: 一、回顾Java EE的发展 二、揭露Java EE的根本性缺陷 三、从Java EE的角度看应用容器云 四、对未来的展望 老实说,今天的观点如果放在一年前,我不大敢讲,会比较有争议。最近
yuanyi928
2018/04/02
8540
应用容器云:接过Java EE的枪
在Java EE7框架中使用MongoDB
中心点创建应用程序的执行在企业环境中,应用程序必须安全、便携和高可用性。它还必须能够与不同的系统交互,但可控的从一个最好的位置。JEE7合并是一个重要的框架的所有特性,它的工作原理很无缝地与MongoDB。本文在创建一个Web应用程序使用MongoDB的手放在存储。 这种安排是…… 这是一个简单的、精益的CRUD应用程序,或者它的一部分,使用一些EJB和JSF JEE7的中坚分子。这个想法是为了使复位候选人在MongoDB,搜索需要的候选人根据技能人,也可以从数据库中删除一个特定候选人。 你需要什么… JE
用户1289394
2018/02/27
1.1K0
在Java EE7框架中使用MongoDB
Lxcfs在容器集群中的使用
背景:我们知道在k8s 的pod 内,使用top/free/df等命令,展示的状态信息是从/proc目录中的相关文件里读取出来的,这些文件默认是读取pod所在节点主机对应文件的数据。
keepyan
2020/03/06
2.8K0
Lxcfs在容器集群中的使用
java ee简介_Java EE 简介
JavaEE 的诞生是为了解决传统 C/S 架构的弊端:客户端臃肿庞大,扩展性差等弊端。 JavaEE 将传统的两层结构细分为了四层。
全栈程序员站长
2022/09/08
1.2K0
将Java EE应用程序部署到Docker Swarm集群
Techeek
2018/01/04
1.9K0
将Java EE应用程序部署到Docker Swarm集群
将Elasticsearch直接连接到Java EE应用程序
时髦的大数据来自3 V:音量,种类和速度。卷是指数据的大小,品种是指不同类型的数据,而速度是指数据处理的速度。为了处理持久性大数据,NoSQL数据库可以更快地写入和读取数据。但由于数量众多,搜索引擎需要查找没有大量计算机能力且耗费太多时间的信息。搜索引擎是一种旨在搜索信息的软件系统; 这种机制使用户获得他们想要的信息变得更加直接和清晰。
February
2018/11/14
1K0
将Java EE应用程序部署到Docker Swarm集群
Docker Swarm 为Docker提供本地集群。Docker Swarm 0.2.0版本的集群 提供了Docker Swarm 的基本介绍,以及如何创建一个简单的具有三节点的集群。作为复习,在这里展示一下Docker Swarm的关键组件:
李志伟
2019/12/17
1.3K0
将Java EE应用程序部署到Docker Swarm集群
将Java EE应用程序部署到Docker Swarm集群
Docker Swarm为Docker提供本地集群。 使用Docker Swarm 0.2.0的集群一文提供了对Docker Swarm的基本介绍,以及如何创建一个简单的三节点集群。作为一个回顾,Docker Swarm的关键组件如下所示:
lemoon1993
2018/01/10
2.5K0
在容器中使用 Java 的资源分配准则
如果说在容器中运行 Java 应用有一条核心定律,那么就是:对于在容器中运行的 Java 进程,不要手工设置 JVM 堆内存。相反的,设置容器的限制。
Java帮帮
2019/11/25
1.5K0
JAVA EE 开发中 常用的API包
API  常见的几个类:lang/util/io/math/net awt --------         用于创建用户界面和绘制图形的所有类。 util ------  包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类                 (字符串标记生成器、随机数生成器和位数组)。 net-------         为实现网络应用程序提供类 lang------         为java编程提供基础类 io  --
用户1220053
2018/02/09
1.1K0
使用JavaMelody监控Java EE应用
JavaMelody的目标是监控QA环境或者生产环境Java或者Java EE应用。JavaMelody不是一个模拟用户请求的工具;它是一个用于对应用上的真实操作进行衡量和和计算统计的工具,这些真实的操作取决于用户在应用上的使用情况。
孟君
2019/10/22
1.1K0
使用JavaMelody监控Java EE应用
Java中的容器
在Java中有常用的三种类型的容器,分别是List 、Map、Set,基于这个三个基本的类型,派生出很多其它的类型,具体关系如下:
付威
2018/12/05
1.8K0
Java中的容器
使用容器进行应用程序路由
本文收录在DZone的容器编制与部署指南中。点击此处阅读更多富有洞察力的文章、行业统计数据等内容!
Techeek
2018/01/15
9160
在Java Project(不是J2EE)中使用freemarker2.3.24
1、从官网下载freemarker的binary release,下载得到的是压缩包,解压后,文件夹里有需要的freemarker.jar文件(只需要这个jar文件,这不像spring或者hibernate等需要很多jar文件),之后将这个freemarker引入到项目中。
克虏伯
2019/04/15
4310
在Java Project(不是J2EE)中使用freemarker2.3.24
浅谈Linux SECCOMP安全机制在容器中的使用
简单的文件复制代码,当seccomp功能打开的时候,代码执行到25行“open(argv[1], O_RDONLY)”时就会 退出,如图:
CNCF
2021/03/15
7.1K0
在java中使用SPI创建可扩展的应用程序
什么是可扩展的应用程序呢?可扩展的意思是不需要修改原始代码,就可以扩展应用程序的功能。我们将应用程序做成插件或者模块。
程序那些事
2020/08/27
1.5K0
在java中使用SPI创建可扩展的应用程序
Java中容器的遍历
当我们用增强for循环遍历非并发容器(HashMap、ArrayList等),如果修改其结构,会抛出异常 ConcurrentModificationException,因此在阿里巴巴的Java规范中有说到:不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。,但是不是真的就不可以在增强for循环中修改结构吗?其原理又是什么呢?
健程之道
2019/11/03
8250
在Docker中开发Java 8 Spring Boot应用程序
在Docker中开发Java 8 Spring Boot应用程序
Nikoace
2018/01/03
2.8K0
使用Docker容器化FastAPI应用程序
在构建和部署应用程序时,Docker 容器化已成为一种常见的做法。通过将应用程序和其依赖项打包在一个独立的容器中,可以轻松地在不同环境之间移动和部署应用程序,同时确保其依赖项的一致性和可重复性。
堕落飞鸟
2023/05/08
1K0
从Java EE到Jakarta EE,企业版Java的发展历程
诞生于1995年的Java语言,年近三旬,甚至比很多同学的年龄还大得多。正所谓三十年河东,三十年河西,有人说Java已廉颇老矣,基本结构过于老套不灵活,但显示情况是它“老而不死”依旧常年霸榜,是棵常青树。
YourBatman
2021/07/14
3.8K0
从Java EE到Jakarta EE,企业版Java的发展历程

相似问题

寻找Java EE 6应用程序

13

使用Spring Pitchfork让Java EE兼容的代码在非Java EE容器中运行

24

JSTL在Java EE 6中的状态

10

EE6/Servlet容器中的HTTPS

11

如何使用Java EE 6 SDK?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文