Mongoose Arguments必须是聚合管道运算符

时间:2017-02-01 10:04:01

标签: angularjs node.js mongodb mongoose

我们正在尝试在NodeJS中构建一个函数,它允许我们将该函数与find或aggregate参数一起使用并返回结果。

find选项工作正常,限制和偏移也可以。但聚合不起作用。我们收到错误

  

参数必须是聚合管道运算符

当我们调用该函数时。

模型看起来像(我删除了一些字段)

product.model.js

var Product = new mongoose.Schema({
name: { //obsolete
    type: String,
    required: true
},
nameSlug: { //obsolete
    type: String,
    required: true
},
views: {
    type: Number,
    min: 0,
    default: 0,
    required: true
},
waterproofLevel: {
    type: Number,
    min: 0,
    max: 3000,
    default: 0,
    required: true
},
productCollection: {
    type: String
},
male: {
    type: Boolean,
    default: true,
    required: true
},
female: {
    type: Boolean,
    default: false, 
    required: true
},
kids: Boolean,
isBestseller: {
    type: Boolean,
    default: false,
    required: true
},
suggestedRetailPrice: {
    type: Number,
    required: true
},
productNumber: {
    type: String,
    required: true
},
ean: {
    type: String,
    minlength: 5,
    maxlength: 13,
    validate: validators.isNumeric({message: 'Invalid EAN: EAN codes consist of 13 digits'}),
    required: true
},
brand: [{
    _id: false,
    name: {
        type: String,
        required: true
    },
    image: [Image]
}],
images: [Image],

});

getProducts函数

module.exports.getProducts = function(req, res) {
console.log('[getProducts controller]');
// default values, because offset and limit are required
var filterBy, sortBy, offset, limit, aggregate;

if(req.query) {

    if(typeof req.query === 'string') {
        req.query = JSON.parse(req.query);
    }

    if(req.query.offset && !isNaN(parseInt(req.query.offset))) {
        offset = parseInt(req.query.offset);
        delete req.query.offset;
    }

    if(req.query.limit && !isNaN(parseInt(req.query.limit))) {
        limit = parseInt(req.query.limit);
        delete req.query.limit;
    }

    // if any filters are provided in the URL, parse them and add to the filtering or aggregate params object.
    if(req.query.aggregate) {
        aggregate = req.query.aggregate;
    }else if(req.query.filter) {
        filterBy = filter(req.query.filter);
    }

    // if any sorting parameters are provided in the URL, parse them and add to the Mongoose sorting object. 
    if(req.query.sort) {
        sortBy = sort(req.query.sort);
    }

    if(req.query.lng && req.query.lat) {
        // TODO find products close to the given coordinates. 
    }

}
if(aggregate){
    console.log("aggregate", aggregate);
    var query = Product.aggregate(aggregate).allowDiskUse(true);
}else{
    var query = Product.find(filterBy);
}

query.skip(offset).limit(limit).exec(function(err, products) {
    var status, response;

    if(err) {
        status = 500;
        response = {message: 'Internal server error. ' + err};
    } else if(!products || products.length == 0) {
        status = 404;
        response = {message: 'No products found with the given search criteria. '};
    } else {
        status = 200;
        response = {message: 'OK', products};
    }

    console.log(status + ' ' + response.message);
    res.status(status).json(response);

});
};

产品系列目前拥有2500种产品。所以,我读了关于allowDiskUsage(true)函数的另一个问题。

我们使用$ api服务调用该函数,该服务是Angular中$ http服务的包装器:

var filter = {
        $match : {
            'brand.name': brand
       }
}
console.log("filter", filter);
$api.get('products', {'aggregate': filter}, function(response){
     console.log(response.data);
}, function(response){
    console.log("error", response.data);
})

当我在函数中记录聚合参数时,它是正确的,它看起来像:aggregate {$match:{'brand.name':'Microsoft'}}

有没有人可以告诉我我失踪了什么?

1 个答案:

答案 0 :(得分:1)

聚合函数接受一组操作 -

你需要通过这个

[{$match:{'brand.name':'Microsoft'}}]

而不是

{$match:{'brand.name':'Microsoft'}}

或者在mongoose中你可以像这样使用流水线 -

Product.aggregate().match({'brand.name':'Microsoft'}).allowDiskUse(true);