简体   繁体   中英

mongoose / MEAN.js - model.find() returns empty array if filtered

im new to mean.js so it could be just wrong syntax, but when i use model.find() with a query inside (option.find({poll_id:1}) it returns an empty array.

poll.server.model.js

'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

/**
 * Poll Schema
 */
var PollSchema = new Schema({
    poll_id: {type:Number},
    user_id: {type:Number},
    poll_question: {type:String},
    poll_language: {type:String},
    poll_description: {type:String},
    poll_description_raw: {type:String},
    poll_weight_additional: {type:Number},
    poll_flag_active:{type:Number,default:1},
    poll_flag_18plus:{type:Number,default:0},
    poll_flag_expire:{type:Number,default:0},
    poll_flag_deleted:{type:Number,default:0},
    poll_flag_moderated:{type:Number,default:0},
    poll_flag_favourised:{type:Number,default:0},
    poll_date_expiration:{type:Date},
    poll_date_inserted:{type:Date,default:Date.now()},
    poll_flag_updated:{type:Date},
    show_thumbs:{type:Number},
    comments:{
        type: Schema.ObjectId,
        ref: 'User'
    }
});

mongoose.model('Poll', PollSchema);

option.server.model.js

'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

/**
 * Option Schema
 */
var OptionSchema = new Schema({
    option_id:{type:Number},
    poll_id:{type:Number},
    option:{type:Number}
});

mongoose.model('Option', OptionSchema);

polls.server.controller.js

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    errorHandler = require('./errors.server.controller'),
    Poll = mongoose.model('Poll'),
    Option = mongoose.model('Option'),
    _ = require('lodash');

/**
 * List of Polls
 */
exports.list = function(req, res) {
    Poll.find().limit(10).sort('_id')/*.populate('user', 'displayName')*/.exec(function(err, polls) {
        if (err) {

            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });

        } else {
            for (var i=0; i < polls.length; i++) {
                // this works, returns an array with 10 items
                Option.find().exec(function(err,docs){
                    console.log(docs); 
                });
                // this doesnt! although i see in the former array that there are options
                // with the poll_id set to 1.
                Option.find({'poll_id':1}).exec(function(err,docs){
                    console.log(docs); 
                });

            }
            res.json(polls);
        }
    });
};

what am i doing wrong? i looked it up but i dont see any post refering to my problem. i tried using model.find().where('poll_id').equals(1) with and without quotes, but nothing. when i run model.find() it works, but no matter how i try to filter it it returns an empty array. thanks in adcvance!

I understand you have imported from MySQL, but the right way to store and search your data using Mongoose would be with population and refs:

var Polls = mongoose.Schema({
  options: [{ type: Schema.Types.ObjectId, ref: 'Options' }]
});

var Options = mongoose.Schema({
  ...
});

Polls
  .find()
  .limit(10)
  .sort('_id')
  .populate('options')
  .exec(function (err, polls) {
    console.log(polls.options); // => [ array of options ]
  });

Relevant docs can be found here http://mongoosejs.com/docs/populate.html

I highly recommend spending some time restructuring your data so you can use the many advantages of population and refs (indexing, cleaner code, etc). Don't make the mistake of trying to force a relational paradigm on a document store. Rip the band aide completely or stick with what you got and know.

That said, you can achieve what you are looking for with your current data like so:

// npm install --save async
var async = require('async');

exports.list = function(req, res, next) {

  Poll.find().limit(10).sort('_id').exec(function (err, polls) {

    // In true HTTP parlance, the correct thing to do here would 
    // be to respond with a 500 instead of a 400. The error would
    // be coming from MongoDB, not a poorly formed request by the
    // client. Remember: 40Xs are for client errors and 50Xs are 
    // for server errors. If this is express, you should also look
    // into using a middleware error handler and passing the error 
    // down the line like so:
    if (err) return next(err);

    // Since you used a return statement above, there is no need for 
    // the if/else but this is a matter of style. If it helps with the
    // readability of your code, keep it. I choose to eliminate because
    // async code has enough nesting as it is!

    // https://github.com/caolan/async#maparr-iterator-callback
    async.map(polls, function (poll, callback) {

      // Now look up your option by its poll_id
      Option.find({'poll_id': poll.poll_id}, function (err, options) {
        if (err) return callback(err);
        poll.options = options;
        callback(null, poll);
      });

    }, function (err, data) {

      // Again, this would be a Mongo error, so pass it down the line to
      // handle as a generic 500.
      if (err) return next(err);

      // The data parameter is your newly mapped polls array
      res.json(data);

    });
  });
};    

Take note of how much more boilerplate it took to achieve without population and refs. Also, under the covers population would only hit the DB twice where as here you're hitting it 11 times. You'll be better off in the long run to change your data now then to give birth to a relational/document store hybrid. I've seen them and they're not pretty ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM