nodejs如何在控制器中动态操作MongoDB聚合?

时间:2017-05-16 07:31:25

标签: javascript node.js mongodb mongoose

我的nodejs控制器中有一个非常loooong聚合:

agentSaleModel.aggregate([
    {
        $match: {
            $and: 
            [{ 
                _id: { $in: req.body.propertyID },
                active : true
            }]
        }
    }, etc....

当我在req.body.propertyID中获取元素时,它的效果很好 喜欢[" property01"," property02"]等......

我的问题是,当req.body.propertyID中没有任何内容时,我也希望聚合工作。 (当它的空白时) - 然后获取所有记录。

这不起作用:

agentSaleModel.aggregate([
    {
        $match: {
            $and: 
            [{ 
                _id: { $in: '' },
                active : true
            }]
        }
    }, etc....

所以不要做"如果"有两组几乎完全相同的代码:

if (req.body.propertyID) {
   ...the entire aggregate... 
} else {
   ...the entire aggregate minus the _id: { $in: req.body.propertyID },... 
}

有更聪明的方法吗?

解!!感谢FluffyNights:)

if (req.body.propertyID!='') {
    var matchStr = { 
        $match: {
            $and: 
            [{ 
                _id: { $in: req.body.propertyID },
                active : true
            }]
        }
    }
} else {
    var matchStr = { 
        $match: {
                active : true
        }
    }
}
agentSaleModel.aggregate([ matchStr, etc..... (rest of pipeline)

3 个答案:

答案 0 :(得分:1)

你可以这样做:

let query = [
    {
        $match: {
            $and: 
            [{ 
                active : true
            }]
        }
    }];
if(req.body.propertyID) {
   query[0]["$match"]["$and"][0]["_id"] = { $in: req.body.propertyID };
}
agentSaleModel.aggregate(query, ...)

您也可以使用正则表达式,例如:

if(!req.body.properyID){
    req.body.propertyID = [ ".*" ];
}
agentSaleModel.aggregate([
{
    $match: {
        $and: 
        [{ 
            _id: { $in: req.body.propertyID },
            active : true
        }]
    }
}, etc....
然而,这可能会变慢。 我不确定如果将null传递给$ in会以你想要的方式工作,你可以尝试一下。

答案 1 :(得分:1)

如何在运行之前尝试构建查询。

例如。

var query = req.body.propertyID ? { $and: [{_id: { $in: req.body.propertyID }, active : true}]} : {active : true}

agentSaleModel.aggregate([
{
   $match: query
}, etc....

希望这有帮助。

答案 2 :(得分:1)

以下是使用computed property names的内联解决方案:

$match: {
  $and: [
    {
      _id: { [ req.body.propertyID ? '$in' : '$exists' ] : req.body.propertyID || true },
      active: true,
    },
  ],
}

req.body.propertyID存在时,查询变为:

_id : { $in : req.body.propertyID }

如果不是:

_id : { $exists : true }

编辑:如果您明确要匹配所有文档,这也会使req.body.propertyID等于"ALL"

let selectAll = ! req.body.propertyID || req.body.propertyID === 'ALL';
const query = {
  $match: {
    $and: [
      {
        _id: { [ selectAll ? '$exists' : '$in' ] : selectAll || req.body.propertyID },
        active: true,
      },
    ],
  },
};
相关问题