MongoDB计算最常见的嵌套数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB计算最常见的嵌套数组相关的知识,希望对你有一定的参考价值。

我有诗集。集合中的文档具有以下结构:

{
"_id" : "Romeo and Juliet",
"acts" : [ 
    {
        "title" : "ACT I",
        "scenes" : [ 
            {
                "title" : "SCENE I. Verona. A public place.",
                "action" : [ 
                    {
                        "character" : "SAMPSON",
                        "says" : [ 
                            "Gregory, o' my word, we'll not carry coals."
                        ]
                    }, 
                    {
                        "character" : "GREGORY",
                        "says" : [ 
                            "No, for then we should be colliers."
                        ]
                    }, 
                    // ...
                    {
                        "character" : "GREGORY",
                        "says" : [ 
                            "To move is to stir; and to be valiant is to stand:", 
                            "therefore, if thou art moved, thou runn'st away."
                        ]
                    }, 
                    {
                        "character" : "SAMPSON",
                        "says" : [ 
                            "A dog of that house shall move me to stand: I will", 
                            "take the wall of any man or maid of Montague's."
                        ]
                    }, 
                    {
                        "character" : "GREGORY",
                        "says" : [ 
                            "That shows thee a weak slave; for the weakest goes", 
                            "to the wall."
                        ]
                    }, 
                    // ...
            },
            // ...
        ]
    },
    // ...
]}

我需要在says对象中找到具有最多对话(scene)的诗。我尝试过使用$group$unwind$sort等,但结果并不正确。

答案

我需要找到场景对象中具有最多对话(说)的诗

这可以通过以下方式解释。

统计所有场景中所有动作的所有动作都表示每首诗中的所有动作,并显示所有诗歌中最大的诗歌文件。

我们的想法是找到所有动作,所有场景和所有行为的最大值,并输出最大的诗文档。

嵌套的$map$max组合输出不同级别的最大值。

$project排除了“maxsaysacrossallacts”字段。

就像是

 db.poems.aggregate([
  {"$addFields":{
    "maxsaysacrossallacts":{
      "$max":{
        "$map":{
          "input":"$acts",
          "as":"maxsaysineachact",
          "in":{
            "$max":{
              "$map":{
                "input":"$$maxsaysineachact.scenes",
                "as":"maxsaysineachscene",
                "in":{
                  "$max":{
                    "$map":{
                      "input":"$$maxsaysineachscene.action",
                      "as":"sayssceneineachaction",
                      "in":{"$size":"$$sayssceneineachaction.says"}
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }},
  {"$sort":{"maxsaysacrossallacts":-1}},
  {"$limit":1},
  {"$project":{"maxsaysacrossallacts":0}}
])

更新:根据下面的评论,如果您需要输出最大说诗文档,您可以使用下面的聚合查询。

计算所有行为中的所有说法并输出最大说数的诗。

db.poems.aggregate([
  {"$addFields":{
    "sumsaysacrossallacts":{
      "$sum":{
        "$map":{
          "input":"$acts",
          "as":"sumsaysineachact",
          "in":{
            "$sum":{
              "$map":{
                "input":"$$sumsaysineachact.scenes",
                "as":"sumsaysineachscene",
                "in":{
                  "$sum":{
                    "$map":{
                      "input":"$$sumsaysineachscene.action",
                      "as":"sayssceneineachaction",
                      "in":{"$size":"$$sayssceneineachaction.says"}
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }},
  {"$sort":{"sumsaysacrossallacts":-1}},
  {"$limit":1},
  {"$project":{"sumsaysacrossallacts":0}}
])
另一答案

你可以尝试下面的聚合,我们是扁平化的行为,然后是场景,然后是行动,最后说要得到对话的总数,$sort按总数计算诗歌

db.poems.aggregate(
    [
        {$addFields : {flatActs : {$reduce : {input : "$acts", initialValue : [], in : {$concatArrays : ["$$value", ["$$this"]]}}}}},
        {$addFields : {flatScenes : {$reduce : {input : "$flatActs.scenes", initialValue : [], in : {$concatArrays : ["$$value", "$$this"]}}}}},
        {$addFields : {flatAction : {$reduce : {input : "$flatScenes.action", initialValue : [], in : {$concatArrays : ["$$value", "$$this"]}}}}},
        {$addFields : {flatSays : {$reduce : {input : "$flatAction.says", initialValue : [], in : {$concatArrays : ["$$value", "$$this"]}}}}},
        {$addFields : {dialogCount : {$size : "$flatSays"}}},
        {$sort : {dialogCount : -1}},
        {$project : {flatActs : 0, flatScenes : 0, flatAction : 0, flatSays : 0}}
    ]
).pretty()

以上是关于MongoDB计算最常见的嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

mongodb 查询求助,嵌套数组里面查东西

在 MongoDB 中聚合双嵌套数组的文档

MongoDB中数组类型相关的操作

MongoDB 嵌套对象数组后查询

MongoDB 嵌套对象数组后查询

从嵌套数组mongodb中删除元素