在 MongoDB Spring Data 中使用多个方面

2024-03-23

我想在一个聚合中运行多个方面以节省数据库往返次数。这是我的弹簧数据代码:

final BalancesDTO total 
        = this.mongoTemplate.aggregate(
                    newAggregation(

                        /*
                         * Get all fund transactions for this user      
                         */
                        match(where("userId").is(userId)),

                        /*
                         * Summarize Confirmed Debits 
                         */
                        facet(  match(where("entryType").is(EntryType.DEBIT)
                                        .andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
                                unwind("history"),                                                                           
                                match(where("history.status").is(TransactionStatus.CONFIRMED)),                     
                                project().andExpression("history.amount").as("historyAmount"),                      
                                group().sum("historyAmount").as("total"),                       
                                project("total")
                             ).as("totalConfirmedDebits"),

                        /*
                         * Summarize Confirmed Credits 
                         */
                        facet(  match(where("entryType").is(EntryType.CREDIT)
                                        .andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
                                unwind("history"),                                                                               
                                match(where("history.status").is(TransactionStatus.CONFIRMED)),                     
                                project().andExpression("history.amount").as("historyAmount"),                      
                                group().sum("historyAmount").as("total"),                       
                                project("total")
                             ).as("totalConfirmedCredits")
                    ),
                    FundTransactions.class,
                    BalancesDTO.class)
        .getUniqueMappedResult();

    LOGGER.debug("total : {}",total.getTotalConfirmedDebits().get(0).getTotal());

当我运行上面的代码时,它给出了以下异常:

java.lang.IllegalArgumentException: Invalid reference 'history'!
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:100) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:72) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.UnwindOperation.toDocument(UnwindOperation.java:94) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:55) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.FacetOperation$Facet.toDocuments(FacetOperation.java:224) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.FacetOperation$Facets.toDocument(FacetOperation.java:168) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.FacetOperation.toDocument(FacetOperation.java:87) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:55) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDocument(Aggregation.java:585) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate$BatchAggregationLoader.prepareAggregationCommand(MongoTemplate.java:3124) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate$BatchAggregationLoader.aggregate(MongoTemplate.java:3107) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1937) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1832) ~[spring-data-mongodb-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at io.tradehack.shared.fundtransactions.FundTransactionsRepositoryImpl.getFundBalances(FundTransactionsRepositoryImpl.java:41) ~[classes/:na]
at io.tradehack.shared.fundtransactions.FundTransactionsRepositoryImpl$$FastClassBySpringCGLIB$$89f7e1a0.invoke(<generated>) ~[classes/:na]

但有趣的是,如果我删除了第二个方面部分,它就可以工作。出现此异常的原因可能是什么?

下面是我想要运行的等效 mongodb 命令:

db.runCommand(
{ "aggregate" : "FundTransactions", 
  "pipeline" : [{ "$match" : { "userId" : "6cd984b9-1c17-402b-be9c-70614e0b8b8e"} }, 

                { "$facet" : { "totalConfirmedDebits" : [{ "$match" : { "entryType" : "DEBIT", 
                                                                    "$and" : [{ "currentStatus" : "CONFIRMED" }] } },
                                                         { "$unwind" : "$history" }, 
                                                         { "$match" : { "history.status" : "CONFIRMED" } }, 
                                                         { "$project" : { "historyAmount" : "$history.amount" } }, 
                                                         { "$group" : { "_id" : null, 
                                                                        "total" : { "$sum" : "$historyAmount" } } }, 
                                                         { "$project" : { "total" : 1 } }],
                               "totalConfirmedCredits" : [{ "$match" : { "entryType" : "CREDIT", 
                                                                    "$and" : [{ "currentStatus" : "CONFIRMED" }] } },
                                                         { "$unwind" : "$history" }, 
                                                         { "$match" : { "history.status" : "CONFIRMED" } }, 
                                                         { "$project" : { "historyAmount" : "$history.amount" } }, 
                                                         { "$group" : { "_id" : null, 
                                                                        "total" : { "$sum" : "$historyAmount" } } }, 
                                                         { "$project" : { "total" : 1 } }]

                             } 

                }], 

    "cursor" : { "batchSize" : 2147483647 } }

)

以下是示例数据:

{
"_id" : "dfe9dd63-6689-4e9f-8494-24efa6191db1",
"userId" : "6cd984b9-1c17-402b-be9c-70614e0b8b8e",
"entryType" : "DEBIT",
"type" : "DEPOSIT",
"createdDateTime" : ISODate("2018-11-11T03:00:00.000+00:00"),
"currentVersion" : 2,
"currentStatus" : "CONFIRMED",
"history" : [
    {
        "referenceId" : null,
        "currency" : "USD",
        "amount" : 1000000,
        "comments" : "Initial fundings",
        "updatedDateTime" : ISODate("2018-11-11T03:00:00.000+00:00"),
        "status" : "PENDING",
        "version" : 1
    },
    {
        "referenceId" : null,
        "currency" : "USD",
        "amount" : 1001000,
        "comments" : "Initial fundings",
        "updatedDateTime" : ISODate("2018-11-11T04:00:00.000+00:00"),
        "status" : "CONFIRMED",
        "version" : 2
    }
]

}

任何帮助将不胜感激。


您可以使用以下方法链接多个方面操作.and() and .as()方法。你应该更换第二个facet方法与and方法如下。

FacetOperation facets = facet(match(where("entryType").is(EntryType.DEBIT)
        .andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
        unwind("history"),
        match(where("history.status").is(TransactionStatus.CONFIRMED)),
        project().andExpression("history.amount").as("historyAmount"),
        group().sum("historyAmount").as("total"),
        project("total")
).as("totalConfirmedDebits"),
        /*
                 * Summarize Confirmed Credits 
         */
.and(match(where("entryType").is(EntryType.CREDIT)
        .andOperator(where("currentStatus").is(TransactionStatus.CONFIRMED))),
        unwind("history"),
        match(where("history.status").is(TransactionStatus.CONFIRMED)),
        project().andExpression("history.amount").as("historyAmount"),
        group().sum("historyAmount").as("total"),
        project("total")
).as("totalConfirmedCredits")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 MongoDB Spring Data 中使用多个方面 的相关文章

随机推荐

  • StackExchange.Redis 简单 C# 示例

    我正在寻找一个非常简单的 C 入门应用程序来使用 StackExchange Redis 我在网上搜索并发现StackExchange Redis https github com StackExchange StackExchange R
  • Tomcat 7 对已修改/不存在的资源返回“304 Not Modified”

    我正在开发一个在 Struts2 和 Tomcat 7 0 42 上运行的 Web 应用程序 我写了一个动态生成jsp文件的action 生成的 jsp 其中包含一些图像引用 并创建包含图像的关联 files 文件夹 该操作在另一个页面中调
  • ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 未触发

    我只是想在我的应用程序中禁用电池优化 我使用了下面的代码片段 Intent intent new Intent String packageName context getPackageName PowerManager pm PowerM
  • 使用 .NET 库 ECDsaCng 验证 BouncyCastle ECDsa 签名

    现有系统使用 Bouncy Castle NET 生成签名 我需要使用 Microsoft ECDsaCng 类验证这些现有签名 考虑以下尝试执行此操作的代码 public static void InterchangeTest Asymm
  • 使 NSWindow 位于前面但不在焦点中

    我希望在所有其他窗口前面添加一个新的 NSWindow 但不让它获得焦点 我可以使用以下命令使其焦点出现在前面 NSApplication thisApp NSApplication sharedApplication thisApp ac
  • 在 WebClient wp7 中重定向时获取当前 Uri

    我希望我不会开始一个已经完成的话题 但我在这里或其他地方都没有找到任何正确的答案 那么我们开始吧 我使用 WebClient 从网页下载 HTML 代码 然后使用该 WebClient 发送新请求 并且网页会重定向我 现在我想知道网站把我放
  • 如何使用 iPhone 相机检查光线强度

    有什么方法可以使用 iPhone 检查光线强度吗 API 允许这样做吗 从 iOS 相机获取亮度 https www transpire com insights blog obtaining luminosity ios camera
  • 如何在 Swift 中获取 UIScrollView 垂直方向?

    如何在 VC 中获得向上 向下滚动 滑动方向 我想在我的 VC 中添加 UIScrollView 或其他内容 可以查看用户是否向上或向下滑动 滚动 然后隐藏 显示UIView取决于它是否是向上 向下手势 如果您使用UIScrollView那
  • 使用 python/bcrypt 将密码保存为用户集合中 mongodb 中的加盐哈希

    我想生成一个加盐密码哈希并将其存储在名为 users 的 MongoDB 集合中 如下所示 users doc username James password
  • 汇编编码 strdup. Malloc 在共享库中调用

    我有一个问题 调用 malloc 时无法编译 strdup 当我不调用 malloc 时 它会完美地编译我的共享库 所以如果有人可以帮助我 那就太好了 这是我的代码 BITS 64 DEFAULT REL global my strdup
  • 如何修复 Chunk.modulesIterable 的弃用警告?

    我是的维护者外部 svg sprite loader https github com karify external svg sprite loader我注意到 当将它与 webpack 5 一起使用时 我收到以下警告 DEP WEBPA
  • 如何编写将所有参数转发给委托命令的包装器 powershell 命令?

    wrapper应该只是打电话delegate 转发传递给包装器的参数 Given wrapper ps1 1 2 Whendelegate ps1 内容 param one two write host one one and two tw
  • 通过连接池发出 http 请求时 Akka Flow 挂起

    我正在使用 Akka 2 4 4 并尝试从 Apache HttpAsyncClient 迁移 未成功 下面是我在项目中使用的代码的简化版本 问题是 如果我向流程发送超过 1 3 个请求 它就会挂起 到目前为止 经过6个小时的调试 我什至找
  • 基于模板的主题观察者模式 - 我应该使用 static_cast 还是dynamic_cast

    我指的是这篇文章使用模板实现主题 观察者模式 http www codeproject com KB architecture observer with templates aspx 我做了一些修改 代码如下 template
  • 找到 O(n) 中所有成员都在列表中的最大区间 [重复]

    这个问题在这里已经有答案了 我在一次采访中被问到这个问题 给定一个整数列表 我们如何找到其所有成员都在给定列表中的最大区间 例如 给定列表 1 3 5 7 4 6 10 那么答案将是 3 7 因为它具有 3 到 7 之间的所有元素 我试图回
  • 使用多个 websocket 连接

    我有一个网站 每月有几千次访问 而且还在不断增长 我正在向我的网站添加新的交互式功能 现在我正在处理一个问题 我应该为所有功能使用一个 websocket 连接 还是应该为我的应用程序的每个交互功能创建新的 websocket 连接 我正在
  • 移动名称中带有空格的文件

    我在 unix 中有一个文件 名称为 这是我的文件 xls 我想将它从一个文件夹移动到另一个文件夹 我写了以下几行 fileName this is my file myDate 20121125 mv FIRST DIR fileName
  • 使用ajax将Flash视频加载到div中

    我有一个客户希望能够从视频缩略图播放列表中进行选择 并且它会替换页面上已有的视频 我还需要观察加载时间 因此认为如果使用 ajax 单击每个视频 则请求该视频会更好吗 我是 ajax 新手 所以不确定这是否是最好的选择 我的页面如下 div
  • /arm64/Image 到 zImage 或 boot.img

    大家好 我一直在试图弄清楚如何使我的 android 内核成为 zImage 或 boot img 我试图弄清楚但没有运气 有人告诉我 zImage 不适用于我的设备 因为它是 arm64 内核 但我想我会再问一次 如果是这种情况 我会尝试
  • 在 MongoDB Spring Data 中使用多个方面

    我想在一个聚合中运行多个方面以节省数据库往返次数 这是我的弹簧数据代码 final BalancesDTO total this mongoTemplate aggregate newAggregation Get all fund tra