【问题标题】:MongoDB aggregate, $addFields not working on $condMongoDB 聚合,$addFields 不适用于 $cond
【发布时间】:2020-12-30 16:45:15
【问题描述】:

我一直在使用调查集合和 $lookup 来查找调查问题的相关答案。

现在我想介绍一个 user_oid 并使用 $addField 创建一个“user_answer_count”。

代码:

Survey.aggregate([
    { $match: { team_oid: mongoose.Types.ObjectId(req.params.t_oid) } },
    { $addFields: { count_questions: { $size: "$questions"} } },
    { $unwind: { path: "$questions" } },


    { $lookup: { from: 'answers', localField: 'questions', foreignField: 'question_oid', as: 'answer' } },
    { $unwind: { path: "$answer", preserveNullAndEmptyArrays: true } },
    { $addFields: { 
        answer_count: { $cond: [{ $eq: [{ $type: "$answer" }, "object" ]}, 1, 0] } },
        user_answer_count: { $cond: [{ $eq: ["$answer.user_oid", mongoose.Types.ObjectId(req.params.u_oid) ]}, 1, 0] }
    },


    { $lookup: { from: 'votes', localField: '_id', foreignField: 'surveyOid', as: 'votes' } },
    { $unwind: { path: "$votes", preserveNullAndEmptyArrays: true } },
    { $addFields: { vote_count: { $cond: [{ $eq: [{ $type: "$votes" }, "object"] }, 0.2, 0] } } },

    {
      $group: {
        _id: "$_id",
        huddle_number: { $first: "$huddle_number" },
        count_questions: { $first: "$count_questions" },
        count_answers: { $sum: "$answer_count" },
        count_votes: { $sum: "$vote_count" },
        count_user_answers: { $sum: "$user_answer_count" },
        sefirot_state: { $first: "$sefirot_state" },
        created_date: { $first: "$created_date" },
        avg_positive: { $avg: "$answer.positive" },
        avg_creative: { $avg: "$answer.creative" },
        avg_focused: { $avg: "$answer.focused" },
        avg_friendly: { $avg: "$answer.friendly" },
        avg_aligned: { $avg: "$answer.aligned" },
        avg_alert: { $avg: "$answer.alert" }
      }
    }
]).exec((err, doc) => {

这里一切正常,第一个 $addField "answer_count" 完美运行。但是第二个“user_answer_count”失败了。

控制台说: Arguments must be aggregate pipeline operators

这是我第一次尝试将 $lookup 与 $addFields 一起使用,欢迎提出建议!

编辑:

示例文档

**Survey**
_id : 5f5a372d9ea9981e7c5773cb
questions :
    0 : 5f522b025dd8993e58283522
    1 : 5f47a892db023557105e2be3
    2 : 5f522a9d5dd8993e58283520
    3 : 5f0e23ef2e0fcb3fe04a7314
    4 : 5f522b285dd8993e58283523
created_date : 2020-09-10T14:24:45.439+00:00
team_oid : 5f44cc20c74f8a444851d9c2
huddle_number : 22
sefirot_state : "Aligned"
__v : 0

**Answer**
_id : 5f58bb04772a5943a0b54ec9
question : "What does "winning" look like in this team?"
question_oid : 5f522bc55dd8993e58283526
user_team_oid : 5f44cc20c74f8a444851d9c2
user_oid : 5f1ef3e8accff82f3cae3957
comment : "It means Cobra Kai Never Die and Only Get Better"
created_date : 2020-09-09T11:22:44.098+00:00
__v : 0

【问题讨论】:

  • 谢谢@turivishal - 我试过这个,但得到了同样的错误......

标签: mongodb aggregate pipeline


【解决方案1】:

修复很少,缺少括号和$cond 语法不正确,这种方式获取数组计数也是错误的。

  • 数组中元素的计数使用$size,用于answer_count
  • 您可以使用$reduce数组运算符获取用户的计数,无需使用$unwind答案数组
  { $lookup: { ... } }, // skipping
  {
    $addFields: {
      answer_count: { $size: "$answer" },
      user_answer_count: {
        $reduce: {
          input: "$answer",
          initialValue: 0,
          in: {
            $cond: [
              { $eq: ["$$this.user_oid", mongoose.Types.ObjectId(req.params.u_oid)] },
              { $add: ["$$value", 1] },
              "$$value"
            ]
          }
        }
      }
    }
  }

Playground

【讨论】:

  • 谢谢@turivishal。这是一个有用的答案,并且效果很好,但是当我应用于我的代码时它不起作用。我想是因为我在aggregate 方法中执行了之前的操作,所以数据已经结构化了?如果你想看看,我在我的问题中添加了其余的聚合。我正在努力解决它。再次感谢,如果我能完成这项工作,我会接受这个答案。
  • 好的,在操场上也为其他收藏提供一些文件,所以我会调查一下
猜你喜欢
  • 2021-08-04
  • 2016-05-30
  • 2019-02-25
  • 2017-08-03
  • 2021-04-20
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多