【问题标题】:Mongo - add field if object in array of sub docs has valueMongo - 如果子文档数组中的对象具有值,则添加字段
【发布时间】:2020-03-01 05:45:33
【问题描述】:

详情

我使用 express 开发调查应用程序,但在获取一些数据方面遇到了困难。

案例:

  • 您可以通过“GET /surveys”获取所有调查。如果用户投票支持调查,则每个调查文档都必须包含hasVoted:mongoose.BooloptionsVote: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,如何添加字段hasVotedoptionsVote


我相信你明白了,所以如果你知道如何更改架构以达到预期的结果,我愿意!


示例:

  1. 数据:
[{
 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}
}]
  1. 路由处理程序:

Where req.user.id='userId1' 然后进行 desired 查询。

  1. 结果
[{ // 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,
}]

【问题讨论】:

    标签: database mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:
    1. 在MongoDB中,您可以按如下方式搜索子文档
    //Mongodb query to search for survey filled by a user
    db.survey.find({ 'votes.user': myUserId })
    

    因此,当您只能在用户投票的地方获得结果时,您真的需要hasVoted 字段吗?

    1. 要拥有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 方便将有助于您进行健全性检查。

    【讨论】:

      猜你喜欢
      • 2017-01-20
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2021-07-26
      • 2020-10-02
      • 2017-12-27
      • 1970-01-01
      • 2022-01-20
      相关资源
      最近更新 更多