MongoDb聚合:在给定array-1和array-2的情况下,如何基于另一个array-2对一个array-1进行分组? [英] MongoDb Aggregation: How can I group an array-1 based on another array-2 when given array-1 and array-2?

查看:131
本文介绍了MongoDb聚合:在给定array-1和array-2的情况下,如何基于另一个array-2对一个array-1进行分组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最初的问题是

MongoDb聚合:您可以在$ lookup阶段的预案中$ unwinding一个输入文档变量吗?

MongoDb Aggregation: Can you $unwind an input document variable in the pipline of a $lookup stage?

考虑以下代码:

{$lookup: {
    from:"mydoc", 
    let: {"c":"$myArray"}, 
    pipeline: [ 
        {$unwind: "$$c"},
    ]
    as:"myNewDoc"
 }}

如果愿意,我将如何放松c?

How would I unwind c if I wanted to?

/////结束原始问题

/////END OF ORIGINAL QUESTION

从汤姆·斯拉伯特(Tom Slabbaert)的评论中,我们现在知道可以在$ lookup阶段的花键中对输入文档变量进行$ unwind.但这是不推荐的.

From Tom Slabbaert's comment we now know that it is possible to $unwind an input document variable in the pipline of a $lookup stage. But it is not recommended.

我要达到什么目的?

What am I trying to achieve?

考虑来自此答案来自poll和castedvote/stackoverflow.com/q/60740127/9953550>我问的一个问题.

Consider these collections, poll and castedvote from this answer from a question I had asked.

我正在尝试获得如下输出:

I am trying to get an output like below:

numberOfVotes: 6,
hasThisUserVoted: true,
numberOfComments: 12,
castedVotesPerChoice:{
    "choiceA": [
        {"_id": ObjectId("..."), "voter": "Juzi", "choice": 0, "pollId": 100 },
        {"_id": ObjectId("..."), "voter": "Juma", "choice": 0, "pollId": 100 },
        {"_id": ObjectId("..."), "voter": "Jane", "choice": 0, "pollId": 100 },
    ],
    "choiceB": [
        {"_id": ObjectId("..."), "voter": "Jamo", "choice": 1, "pollId": 100 },
        {"_id": ObjectId("..."), "voter": "Juju", "choice": 1, "pollId": 100 },
        {"_id": ObjectId("..."), "voter": "Jana", "choice": 1, "pollId": 100 }
    ],
    "choiceC": [ ]
}

我当前的实施方式:

db.poll.aggregate([
    {"$match": {"_id": 100}}, 
    // ...lookup to get comments
    {"$lookup": {
        "from":"castedvotes", 
        "let": {"pollId":"$_id"}, 
        "pipeline":[
            {"$match":
                {"$expr":
                    {"$eq": ["$pollId", "$$pollId"]},
            }},
        ], 
        "as":"votes" // will use this to get number of votes and find out if the authenticated user has voted.
    }},
    {"$unwind":"$choices"},
    {"$lookup": {
        "from":"castedvotes", 
        "let": {"c":"$choices"}, 
        "pipeline":[
            {"$match":
                {"$expr":
                    {"$eq": ["$choice", "$$c.id"]},
            }},
        ], 
        "as":"votesPerChoice"
    }},
])

我目前的实现方式存在的问题是,它对同一个集合进行了两次查找,我觉得这是不必要的,这会使代码变得不干燥. 有了$unwind,我知道我可以按照此处中所述取消$unwind

The issue I have with my current implementation is that it is doing a lookup on the same collection twice I feel like this is unnecessary and it makes the code not dry. With $unwind I know I can un-$unwind as described here.

所以我的问题是,如何通过一个$ lookup到强制投票集合中获得所需的输出?由于两个查找返回相同的数据.

So my question is how can I get my desired output with one $lookup to the casted vote collection? Since both lookups return the same data.

或者换个角度问这个问题,当给定array-1和array-2时,如何在mongodb聚合中基于另一个array-2对一个array-1进行分组?

Or to ask the question differently how can I group an array-1 based on another array-2 in mongodb aggregation when given array-1 and array-2?

此问题回答了如何通过将$lookup阶段构造为特定的形式,在mongodb聚合中基于另一个数组对数组进行分组道路.它不能回答我的问题.

This question answers how to group arrays based on another array in mongodb aggregation by structuring the $lookup stage a certain way. It does not answer my question.

推荐答案

如果我了解拼图",正确发布(发布标题和 EDIT 是不同的用例),我们只需一个$lookup即可获得所需的结果:

If I've understood the "puzzle" post correctly (Post title and EDIT are different use cases), we can get the desired result with a single $lookup:

db.poll.aggregate([
  {
    "$match": {
      "_id": 100
    }
  },
  {
    "$lookup": {
      "from": "castedvotes",
      "localField": "pollId",
      "foreignField": "choices.id",
      "as": "voters"
    }
  },
  {
    $project: {
      numberOfVotes: {
        $size: "$voters"
      },
      hasThisUserVoted: {
        $in: [
          "$_id",
          "$voters.pollId"
        ]
      },
      /**How to calculate it?*/
      numberOfComments: {
        $multiply: [
          {
            $size: "$voters"
          },
          2
        ]
      },
      castedVotesPerChoice: {
        $arrayToObject: {
          $map: {
            input: "$choices",
            as: "choice",
            in: {
              k: "$$choice.name",
              v: {
                $filter: {
                  input: "$voters",
                  as: "voter",
                  cond: {
                    $eq: [
                      "$$voter.choice",
                      "$$choice.id"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  }
])

MongoPlayground

这篇关于MongoDb聚合:在给定array-1和array-2的情况下,如何基于另一个array-2对一个array-1进行分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆