Mongo - 如果子文档数组中的对象具有值,则添加字段
Posted
技术标签:
【中文标题】Mongo - 如果子文档数组中的对象具有值,则添加字段【英文标题】:Mongo - add field if object in array of sub docs has value 【发布时间】:2020-03-01 05:45:33 【问题描述】:详情
我使用 express 开发调查应用程序,但在获取一些数据方面遇到了困难。
案例:
您可以通过“GET /surveys”获取所有调查。如果用户投票支持调查,则每个调查文档都必须包含hasVoted:mongoose.Bool
和optionsVote:mongoose.Map
。 (SurveySchema 如下)
您可以通过“POST /surveys/vote”为调查投票
您可以看到任何调查的结果只有您投票支持它
new Schema(
question:
type: mongoose.Schema.Types.String,
required: true,
,
options:
type: [
type: mongoose.Schema.Types.String,
required: true,
]
,
optionsVote:
type: mongoose.Schema.Types.Map,
of: mongoose.Schema.Types.Number,
,
votesCount:
type: mongoose.Schema.Types.Number,
,
votes:
type: [
user:
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
,
option: mongoose.Schema.Types.Number,
]
,
)
目标:
所以问题的目标是如果votes
数组中有“投票”子文档user===req.user.id
,如何添加字段hasVoted
和optionsVote
?
我相信你明白了,所以如果你知道如何更改架构以达到预期的结果,我愿意!
示例:
-
数据:
[
id:"surveyId1
question:"Question",
options:["op1","op2"],
votes:[user:"userId1", option:0]
votesCount:1,
optionsVote:"0":1,"1":0
,
id:"surveyId2
question:"Question",
options:["op1","op2"],
votes:[user:"userId2", option:0]
votesCount:1,
optionsVote:"0":1,"1":0
]
-
路由处理程序:
Where req.user.id='userId1'
然后进行 desired 查询。
-
结果
[ // Voted for this survey
id:"surveyId1
question:"Question",
options:["op1","op2"],
votes:[user:"userId1", option:0]
votesCount:1,
optionsVote:"0":1,"1":0,
hasVoted:true,
, // No voted for this survey
id:"surveyId2
question:"Question",
options:["op1","op2"],
votesCount:1,
]
【问题讨论】:
【参考方案1】:-
在MongoDB中,您可以按如下方式搜索子文档
//Mongodb query to search for survey filled by a user
db.survey.find( 'votes.user': myUserId )
因此,当您只能在用户投票的地方获得结果时,您真的需要
hasVoted
字段吗?
要拥有optionsVote
字段,首先我希望optionsVote
的架构为option: "a", count:1
。您可以选择以下任何一种方法。
A.通过增加POST /survey/vote
时投票选项的计数,设法在更新时更新optionsVote
字段。
B.另一种方法是根据GET /survey
时的votes
条目计算optionsVote
。你可以通过聚合来做到这一点
//Mongodb query to get optionsVote:option: "a", count:1 from votes: user:"x", option:"a"
db.survey.aggregate([
$unwind: "$votes" ,
$group:
"_id": "id": "_id", "option": "$votes.option" ,
optionCount: $sum: 1
,
$group: "_id": "$_id.id" ,
optionsVote: $push : option: "$_id.option", count: "$optionCount" ,
votes: $push : '$votes'
])
//WARNING: I haven't tested this query, this is just to show the approach -> group based on votes.option and count all votes for that option for each document and then create optionsVote field by pushing all option with their count using $push into the field `optionsVote`
我推荐方法 A,因为我认为 POST 操作会比 GET 操作少得多。也更容易实现。话虽如此,将查询放在 B 方便将有助于您进行健全性检查。
【讨论】:
以上是关于Mongo - 如果子文档数组中的对象具有值,则添加字段的主要内容,如果未能解决你的问题,请参考以下文章