在MongoDB中展开空数组

6
这与这个问题非常相似,但是使用类似的方法时,我只得到了包含子文档的文档列表。
我的模式很简单,有些问题可以投票。我的模式(为简单起见删除了一些字段):
var mongoose = require('mongoose');

var voteSchema = new mongoose.Schema({
  value: Number,
});

// Document schema for polls
exports.PollSchema = new mongoose.Schema({
    question: { type: String, required: true },
    votes: [voteSchema],
});

我希望有一个包含所有问题及其对应分数的列表。分数是voteSchema中'value'字段的总和。
我试图使用$cond来确保空投票文档被替换为至少一个值为0的投票子文档。但不幸的是,当使用它时,所有的totalScore字段都为0。如果不使用它,则只能得到非空投票的正确totalScore。
Poll.aggregate([
    { $project: {
        _id: 1,
        question: 1,
        totalScore : 1,
        votes : { $cond : [ { $eq : ["$votes.length", 0]}, '$votes', [ { value : 0} ]] }
    }},
    { $unwind: "$votes" },
    { $group: {
        _id : "$_id",
        question: { $first: "$question" },
        totalScore : { $sum: "$votes.value" }
    }},
], function(error, polls) {
    console.dir(polls);
});
2个回答

20
如果您的空 votesnull(不存在),请尝试使用:
{ $ifNull : [ "$votes", [ { value : 0 } ] ] }  

改为:

{ $cond : [ { $eq : [ "$votes.length", 0 ] }, '$votes', [ { value : 0 } ] ] }  

如果你的空 votes[](空数组):

{ $cond : [ { $eq : [ "$votes", [] ] }, [ { value : 0 } ], '$votes' ] }  

关于$cond运算符的一些内容:

它的语法为:{ $cond: [ <boolean-expression>, <true-case>, <false-case> ] }

但是您使用它时,像这样:{ $cond: [ <boolean-expression>, <false-case>, <true-case> ] }

如果votes不存在或为空数组(布尔条件为true),则应该使用[{ value: 0 }]代替它(将[{ value: 0 }]粘贴到$cond运算符数组的第2个项目中)。此外,在这种情况下,length属性不可访问。


2
我真是太傻了。非常感谢你。这个代码解决了问题:votes : { $cond : [ { $eq : ["$votes", [] ]}, [ { value : 0} ], '$votes'] } - Andy Abgottspon
1
如果我需要检查数组是否为空或者为null怎么办? - mortadelo

0
如果您需要检查所有的:空数组,null 和空值,可以像这样操作:
{
  $cond: [
    {
      $in: [
        "$my_array",
        [
          null,
          undefined,
          []
        ]
      ]
    },
    "inCaseTrueValue",
    "inCaseFalseValue"
  ]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接