简体   繁体   English

Node.js如何在控制器中动态操纵MongoDB聚合?

[英]nodejs how to dynamically manipulate your MongoDB aggregate in your controller?

I have a very loooong aggregate in my nodejs controller: 我的nodejs控制器中有一个非常宽松的集合:

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

And it works great when I got elements in my req.body.propertyID like ["property01","property02"] etc... 当我在req.body.propertyID中获得诸如[“ property01”,“ property02”]等元素时,它的效果很好。

My problem is that I also want the aggregate to work when there are nothing in req.body.propertyID. 我的问题是,当req.body.propertyID中没有任何内容时,我也希望聚合工作。 (when its blank) - and then get all records. (空白时)-然后获取所有记录。

This does not work: 这不起作用:

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

So rather than doing an "if" with two huge sets of almost identical code: 因此,与其对两组几乎完全相同的代码进行“如果”分析:

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

Is there a smarter way to do this? 有更聪明的方法吗?

SOLUTION!! 解!! Thanks to FluffyNights :) 感谢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)

you could do it like this: 您可以这样做:

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

you could also use regex, like: 您还可以使用正则表达式,例如:

if(!req.body.properyID){
    req.body.propertyID = [ ".*" ];
}
agentSaleModel.aggregate([
{
    $match: {
        $and: 
        [{ 
            _id: { $in: req.body.propertyID },
            active : true
        }]
    }
}, etc....

however, this might get slow. 但是,这可能会变慢。 Im not sure if passing null to $in would work the way you want, you could try it though. 我不确定是否将null传递给$ in是否可以按照您想要的方式工作,但是您可以尝试一下。

What about trying to construct query before running it. 尝试在运行查询之前构造查询呢?

For example. 例如。

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

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

Hope this helps. 希望这可以帮助。

Here's an inline solution using computed property names : 这是使用计算出的属性名称的内联解决方案:

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

When req.body.propertyID exists, the query becomes: 当存在req.body.propertyID时,查询变为:

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

If not: 如果不:

_id : { $exists : true }

EDIT : this will also allow req.body.propertyID to equal "ALL" if you explicitly want to match all documents: 编辑 :如果您明确想匹配所有文档,这还将允许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,
      },
    ],
  },
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 MongoDB $match 动态构建为字符串 - Building your MongoDB $match as a string dynamically 如何检查您是否确实从聚合中获得了结果 - How to check if you actually got an result from your aggregate 是否可以操作不在您网站上的 Google 地图? - Is It Possible To Manipulate a Google Map that is NOT on your site? NodeJS中数据库的解决方案是什么 - What is your solution to database in NodeJS 您如何根据 Express 和 MongoDB 中的角色在将 JSON 数据发送到您的前端之前对其进行过滤? - How do you filter your JSON data before it is send to your front end based on role in Express and MongoDB? 使用fetch()的NodeJS + Express:如何绕过Javascript中的“您的连接不是私有的”? - NodeJS + Express using fetch(): How to bypass “Your connection is not private” in Javascript? 是否可以将后台脚本连接到mongoDB服务器? 如果是,如何? - Is it possible to connect your background script to mongoDB server? If Yes, How? 是否可以动态重写您的JavaScript - Is it possible to rewrite your javascript dynamically 如何使用 Ajax 调用动态调用 API 中的 ActionResult? - How to dynamically call an ActionResult in your API by using an Ajax-call? 如何将动态生成的元素保存到数据库中? - How do you save a dynamically generated element to your database?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM