mongoDB:如何撤消$ unwind

编程入门 行业动态 更新时间:2024-10-25 06:26:37
本文介绍了mongoDB:如何撤消$ unwind的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

请考虑以下测试结果集合:

Consider this collection of test results:

[{ _id: ObjectId(...), name: "Test1", acts: [ { name: "act1", tests: [ {name: "test1", result: true}, {name: "test2", result: true}] }] }, { _id: ObjectId(...), name: "Test2", acts: [ { name: "act1", tests: [ {name: "test1", result: true}, {name: "test2", result: false}] }, { name: "act2", tests: [ {name: "test3", result: true}] }] }]

我正在尝试使用聚合来创建一个包含所有测试结果之和的计算字段,我想要这样的东西:

I'm trying to use aggregations to create a calculated field with the sum of all test results, I want something like this:

[{ _id: ObjectId(...), name: "Test1", result: true, //new aggregated value acts: [ { name: "act1", result: true, //new aggregated value tests: [ {name: "test1", result: true}, {name: "test2", result: true}] }] }, { _id: ObjectId(...), name: "Test2", result: false, //new aggregated value acts: [ { name: "act1", result: false, //new aggregated value tests: [ {name: "test1", result: true}, {name: "test2", result: false}] }, { name: "act2", result: true, //new aggregated value tests: [ {name: "test3", result: true}] }] }]

我尝试使用聚合和$ unwind,$ project和$ group:

I have tried using aggregate and $unwind, $project and $group:

aggregate([ {$unwind: "$acts"}, {$unwind: "$acts.tests"}, {$project: {name: 1, acts: 1, failed: {$cond: {if: {$eq: ["$acts.tests.test", "true" ]}, then: 0, else: 1}}}}, {$group: {_id: "$_id", failedCount: {$sum: "$failed"}, acts: {$push: "$acts.tests"}}} ])

但是我无法使它撤消$ unwind操作,我只得到了与原始数据不同的结果数据结构. 是否有可能使结果看起来与原始集合完全一样,但具有新的汇总值?

But I can't get it to reverse the $unwind operation, I only get the resulting data structure to differ from the original. Is it possible to get the result to look exactly like the original collection but with the new aggregated values?

/gemigspam

/gemigspam

推荐答案

如何处理此问题有一个特殊的技巧,但是首先,如果您拥有可用的MongoDB 2.6或更高版本,则实际上可以执行所需的操作而无需使用 $unwind .如果要处理大量文档,这对性能非常方便.

There is a particular trick to how this is handled, but firstly if you have MongoDB 2.6 or greater available then you can actually do what you want without using $unwind. This can be very handy for performance if you are processing a lot of documents.

此处的主要运算符是 $map 处理适当的数组,并使用 $allElementsTrue 运算符评估您的结果"字段.这里使用"map"可以对内部"tests"数组进行测试,以查看其中的"result"字段都满足真实条件的位置.在外部数组的情况下,可以根据需要将此结果"放入那些文档中,当然,对文档的完整评估遵循相同的规则:

The key operators here are $map which processes arrays in place and the $allElementsTrue operator which will evaluate your "result" fields. The usage of "map" here allows both the testing of the inner "tests" array to see where the "result" fields in there all meet the true condition. In the outer array case, this "result" can be placed into those documents as you require, and of course the full evaluation for the document follows the same rules:

db.test.aggregate([ { "$project": { "name": 1, "result": { "$allElementsTrue": { "$map": { "input": "$acts", "as": "act", "in": { "$allElementsTrue": { "$map": { "input": "$$act.tests", "as": "test", "in": "$$test.result" } } } } } }, "acts": { "$map": { "input": "$acts", "as": "act", "in": { "name": "$$act.name", "result": { "$allElementsTrue": { "$map": { "input": "$$act.tests", "as": "test", "in": "$$test.result" } } }, "tests": "$$act.tests" } } } }} ])

在早期版本中执行此操作的方法要求您 $group > 分两步进行,以便在对结果"字段再次进行测试时重建"阵列.此处的另一个区别还在于使用 $min 运算符因为false将被认为是小于true的值,并具有相同的"allElements"概念:

The way to do this in earlier versions requires you to $group back in two steps in order to "rebuild" the arrays while doing the tests on those "result" fields again. The other difference here is also using the $min operator as false will be considered a lesser value than true and evaluates to the same "allElements" concept:

db.test.aggregate([ { "$unwind": "$acts" }, { "$unwind": "$acts.tests" }, { "$group": { "_id": { "_id": "$_id", "name": "$name", "actName": "$acts.name" }, "result": { "$min": "$acts.tests.result" }, "tests": { "$push": { "name": "$acts.tests.name", "result": "$acts.tests.result" } } }}, { "$group": { "_id": "$_id._id", "name": { "$first": "$_id.name" }, "result": { "$min": "$result" }, "acts": { "$push": { "name": "$_id.actName", "result": "$result", "tests": "$tests" } } }} ])

更多推荐

mongoDB:如何撤消$ unwind

本文发布于:2023-11-22 18:43:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1618567.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:mongoDB   unwind

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!