gpt4 book ai didi

javascript - Mongoose 选择子文档字段

转载 作者:行者123 更新时间:2023-11-30 17:16:53 24 4
gpt4 key购买 nike

我有这样的架构:

mongoose.model "Ticket", {
title: String
body: String
likes: Number
comments: [{
body: String
upvotes: Number
downvotes: Number
}]
}

我要查询的代码

q = @model.findOne {"comments._id": oid}, {"comments.$": 1}

q.select "comments.upvotes"
q.exec (err, result) =>
console.log(result.comment[0].downvotes) # 6

如您所见,选择对子文档不起作用,它还会返回未选择的字段。如何解决?

最佳答案

这就是 MongoDB 处理数组元素基本投影的方式。虽然您可以这样做:

Model.findOne({}, { "comments.upvotes": 1 },function(err,doc) {

})

这只会从评论数组的子文档中为所有匹配条件的文档和所有数组元素返回“upvotes”字段,当然,您不能将其与使用 positional $ 的选定位置投影结合使用运算符(operator)。这基本上源于“理论”,即通常您实际上想要返回整个数组。所以这就是它一直以来的运作方式,而且不太可能很快改变。

为了得到你想要的,你需要由 aggregation framework 提供的文档操作扩展功能。 .这使您可以更好地控制文档的返回方式:

Model.aggregate(
[
// Match the document containing the array element
{ "$match": { "comments._id" : oid } },

// Unwind to "de-normalize" the array content
{ "$unwind": "$comments" },

// Match the specific array element
{ "$match": { "comments._id" : oid } },

// Group back and just return the "upvotes" field
{ "$group": {
"_id": "$_id",
"comments": { "$push": { "upvotes": "$comments.upvotes" } }
}}
],
function(err,docs) {


}
);

或者在 2.6 之后的现代版本的 MongoDB 中,您甚至可以这样做:

Model.aggregate(
[
{ "$match": { "comments._id" : oid } },
{ "$project": {
"comments": {
"$setDifference": [
{ "$map": {
"input": "$comments",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el._id", oid ] },
{ "upvotes": "$$el.upvotes" },
false
]
}
}},
[false]
]
}}
}}
],
function(err,docs) {

}
)

并且使用 $map$setDifference运算符在不首先处理 $unwind 的情况下对数组内容进行“在线”过滤阶段。

因此,如果您希望更好地控制文档的返回方式,那么在处理嵌入式文档时,聚合框架就是实现这一目标的方式。

关于javascript - Mongoose 选择子文档字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25960641/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com