Mongo AddToSet将多个对象合并为一个数组

时间:2017-05-02 21:15:31

标签: mongodb mongodb-query aggregation-framework pymongo

我试图在Mongo中聚合时使用$ addToSet将多个对象添加到单个数组中。

数据的格式可能不是最好的,但我没有能力对其进行更改。以下是我查询的文档类型的示例:

{
    "question" : "How tall is the CN Tower?",
    "answer" : "553.3 metres",
    "user": "user_1"
    "information" : {
        "info_details" : {
            "info_1" : {
                "score" : 23,
                "size" : 855,
                "total" : 29,
            },
            "info_2" : {
                "score" : 1234,
                "size" : 1000,
                "total" : 3,
                "index" : "index_1",
                "rank" : 1
            }
        }
    }
}

下面是一个示例查询(省略了$ project部分)。虽然双$ addToSet不起作用,但我把它放在那里,因为它显示了我想要在逻辑上完成的事情。请注意,这两个信息对象可能具有不同的字段和值。

...{
  "$group": {
    "_id": {
      "question": "$doc.questionId",
      "answer": "$doc.answerCandidateId",
      "user": "$doc.user"
    },
    "info": {
      "$addToSet": {
        "score": "$doc.information.info_details.info_1.score",
        "size": "$doc.information.info_details.info_1.size",
        "total": "$doc.information.info_details.info_1.total"
      },

      // This second addToSet overwrites the first info value (does not work as I want it to)
      "info": {
        "$addToSet": {
        "score": "$doc.information.info_details.info_2.score",
        "size": "$doc.information.info_details.info_2.size",
        "total": "$doc.information.info_details.info_2.total",
        "index": "$doc.information.info_details.info_2.index",
        "rank": "$doc.information.info_details.info_2.rank"
        }
      }
    }
  }
}

我的目标是拥有一个"信息"使用$ group操作中的所有信息对象(减去重复项)进行设置。

{
    "question": "question_1",
    "answer": "answer_1",
    "user": "user_1",
    "info": [ {"score": 23, "size": 855, "total": 29}, {"score": 1234, "size": 1000, "total": 3, "index": "index_1", "rank": 1}]
}

有没有办法可以在$ group操作中将多个对象添加到同一个集合中?

1 个答案:

答案 0 :(得分:2)

您可以尝试以下基于mongo版本的解决方案。

这里的想法是将动态密钥更改为标记的密钥值结构,即更改嵌入式文档info_1& info_2进入嵌入式数组,然后是$unwind& $group

Mongo版本3.4

您可以使用$objectToArrays运算符将嵌入文档转换为嵌入式数组。

db.collection.aggregate({
    $addFields: {
        information: {
            $objectToArray: "$information.info_details"
        }
    }
}, {
    $unwind: "$information"
}, {
    $group: {
        _id: {
            question: "$question",
            answer: "$answer",
            user: "$user"
        },
        info: {
            $addToSet: "$information.v"
        }
    }
})

Mongo版本3.2

您可以使用[]括号来执行类似的操作,将嵌入式文档转换为嵌入式数组。

db.collection.aggregate({
    $project: {
        question: 1,
        answer: 1,
        user: 1,
        information: ["$information.info_details.info_1", "$information.info_details.info_2"]
    }
}, {
    $unwind: "$information"
}, {
    $group: {
        _id: {
            question: "$question",
            answer: "$answer",
            user: "$user"
        },
        info: {
            $addToSet: "$information"
        }
    }
})