我在MongoDB中有下面的对象,我的后端使用nodeJS.从DB中检索数据。 "_id": "idq2"
和 "_id": "id1"
是在API体中给我们的。
questions = [
{
"_id": "idq1"
"questiontext": "some question",
"author": "auth2",
"Answers": []
},
{
"_id": "idq2"
"questiontext": "some question",
"author": "auth1",
"Answers": [
{
"_id": "id1",
"author": "auth1",
"comments" [
{
"author": "auth1",
"comment": "some comments",
"rate": 1,
"_id": "idc1"
}
, {
"comment": "some comments",
"_id": "idc2"
"rate": 3
}
, {
"comment": "some comments",
"_id": "idc3"
"rate": 2
}
, {
"comment": "some comments",
"_id": "idc4",
"rate": 5
}
]
},
{
"_id": "id2",
"author": "auth2",
"comments" []
}
]
}]
假设我有"_id"。"idq2 "和"_id": "id1", 我试图得到下面的对象.
预期的结果是:
Answer = {
"_id": "id1",
"author": "auth1",
"comments" [
{
"author": "auth1",
"comment": "some comments",
"rate": 1,
"_id": "idc1"
},
{
"comment": "some comments",
"_id": "idc3"
"rate": 2
}
, {
"comment": "some comments",
"_id": "idc2"
"rate": 3
}
]
}
把它变成一个简单的问题。如何得到一个单一的 "Answers "对象,其中包含 "id1 "和前3条评论,按rate参数升序排列,该对象应该是一个单一的对象。
你需要尝试 聚合管道 对于这个:
db.collection.aggregate([
/** Filter docs with required criteria */
{
$match: { "_id": "idq2", "Answers._id": "id1" }
},
/** get only one needed element from `Answers` array & now `Answers` will be an object */
{
$project: {
_id: 0,
Answers: { $arrayElemAt: [ { $filter: { input: "$Answers", cond: { $eq: [ "$$this._id", "id1" ] } } }, 0 ] }
}
},
/** Unwind `comments` array to do sorting */
{
$unwind: "$Answers.comments"
},
{
$sort: {
"Answers.comments.rate": 1
}
},
/** group back based on `Answers._id` & push comments back to `comments` array */
{
$group: {
_id: "$Answers._id",
author: { $first: "$Answers.author" },
comments: { $push: "$Answers.comments" }
}
}
])
测试: mongoplayground
注意: 此查询将返回一个空数组 []
如果没有任何文档符合 $match
标准,否则将在响应中返回一个对象数组。记住 .aggregate()
将始终返回一个数组。