Mongodb展开数组嵌套在数组中

时间:2018-03-30 15:38:03

标签: mongodb mongodb-query

这是我的收藏:

db.questions.insertMany([
  {
    "content": [
      {
        "languageId": "en",
        "text": "What are you planning to buy today at the supermarket?"
      },
      {
        "languageId": "nl",
        "text": "Wat ben je van plan om vandaag in de supermarkt te kopen?"
      },
    ],
    "type": "multipleChoice",
    "multipleChoice": {
      "numAnswers": { "min": 1, "max": 1 },
      "possibleAnswers": [
        {
          "sequence": 1,
          "content": [
            {
              "languageId": "en",
              "text": "apples"
            },
            {
              "languageId": "nl",
              "text": "appels"
            },
          ],
        },
        {
          "sequence": 2,
          "content": [
            {
              "languageId": "en",
              "text": "peers"
            },
            {
              "languageId": "nl",
              "text": "peren"
            },
          ],
        },
      ],
    }
  },
  {
    "content": [
      {
        "languageId": "en",
        "text": "How do you feel?"
      },
      {
        "languageId": "nl",
        "text": "Hoe voel je je?"
      },
    ],
    "type": "ranking1to5",
  }
]);

我想转换为两个content数组中的一种语言。所以我想要输出:

{
    "_id" : ObjectId("5abe4c09d3831890de28ec8f"),
    "content" : 
        {
            "languageId" : "en",
            "text" : "What are you planning to buy today at the supermarket?"
        }, 
    "type" : "multipleChoice",
    "multipleChoice" : {
        "numAnswers" : {
            "min" : 1.0,
            "max" : 1.0
        },
        "possibleAnswers" : [ 
            {
                "sequence" : 1.0,
                "content" : 
                    {
                        "languageId" : "en",
                        "text" : "apples"
                    }
            }, 
            {
                "sequence" : 2.0,
                "content" :  
                    {
                        "languageId" : "en",
                        "text" : "peers"
                    }
            }
        ]
    }
}

/* 2 */
{
    "_id" : ObjectId("5abe4c09d3831890de28ec90"),
    "content" :  
        {
            "languageId" : "en",
            "text" : "How do you feel?"
        },
    "type" : "ranking1to5"
}

我尝试使用$unwind$match$group来解决此问题。我走得很远只有最后一块不起作用:

db.getCollection('questions').aggregate([
    { $unwind: "$content" },
    { $match: { "content.languageId": "en" } },
    { $unwind: { path: '$multipleChoice.possibleAnswers', preserveNullAndEmptyArrays: true } },
    { $unwind: { path: '$multipleChoice.possibleAnswers.content', preserveNullAndEmptyArrays: true } },
    { $match: { "multipleChoice.possibleAnswers.content.languageId": "en" } },
    { $group: { _id: "$_id", content: { $first: "$content" }, type: { $first: "$type" }, multipleChoice: { $addToSet: "$multipleChoice" } } }
])

问题是multipleChoice重复,而这应该是possibleAnswers。此外,还应包含没有multipleChoice对象的问题。

特别感谢任何帮助!!

1 个答案:

答案 0 :(得分:1)

它看起来非常适合$redact。请尝试以下聚合:

db.questions.aggregate(
    [
        {
            $redact: {
                $cond: {
                    if: {
                        $eq: [
                            { $ifNull: [ "$languageId", "en" ] },
                            "en"
                        ]
                    },
                    then: "$$DESCEND",
                    else: "$$PRUNE"
                }
            }
        },
        {
            $addFields: {
                "content": { $arrayElemAt: [ "$content", 0 ] },
                "multipleChoice.possibleAnswers": {
                    $map: {
                        input: "$multipleChoice.possibleAnswers",
                        as: "possibleAnswer",
                        in: {
                            "sequence": "$$possibleAnswer.sequence",
                            "content": { $arrayElemAt: [ "$$possibleAnswer.content", 0 ] }
                        }
                    }
                }
            }
        },
        {
            $redact: {
                $cond: {
                    if: { $eq: [ "$possibleAnswers", null ] },
                    then: "$$PRUNE",
                    else: "$$DESCEND"
                }
            }
        }
    ]
);