Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
836 views
in Technique[技术] by (71.8m points)

aggregation framework - Unwind empty array in mongodb

This is very similar to this question, however, when using a similar approach, I keep getting a list of only the documents that contain subdocuments.

I have a simple schema with questions that can be up and down voted. My schema (I removed some fields for simplicity):

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],
});

I want to have a list with all questions and their respective score. A score is the sum of the 'value' field in voteSchema.

I'm trying to use $cond to make sure the empty votes document is replaced with at least one vote subdocument with a value of 0. Unfortunately, when using it, all my totalScore fields are 0. If not using it, I get the correct totalScore, but only for the non empty ones.

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);
});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If your empty votes is null (not exists), try to use:

{ $ifNull : [ "$votes", [ { value : 0 } ] ] }  

instead of:

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

If your empty votes is [] (empty array):

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

And some about $cond operator:

Its syntax: { $cond: [ <boolean-expression>, <true-case>, <false-case> ] }.

But you used it, like: { $cond: [ <boolean-expression>, <false-case>, <true-case> ] }.

If votes not exists or empty array (boolean condition is true) you should use [ { value : 0} ] instead of it (paste [ { value : 0} ] in 2 item of $cond operator array).
Also, length property is not accessable in this case.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...