将JSON查询条件转换为MongoDB / Mongoose操作

pen*_*ngz 5 javascript mongoose mongodb node.js

我在客户端的Angular 8和NodeJS 12的服务器端使用MongoDB 4 / Mongoose 5构建应用程序。

我有一个由Angular查询构建器模块以JSON格式生成的查询。JSON对象将通过POST请求发送到后端。

问题:如何将JSON查询转换为MongoDB运算符以执行数据库查询?

这是由查询生成器插件生成的简单查询的示例。请注意“嵌套” AND / OR条件的多个级别的要求。

{
  "condition": "and",
  "rules": [
    {
      "field": "Brief_D_Reactiedatum",
      "operator": "!=",
      "value": "Eventtoets_Fn"
    },
    {
      "condition": "or",
      "rules": [
        {
          "field": "Alleen_AO",
          "operator": "=",
          "value": "Parkeerreden"
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

mic*_*ckl 5

您需要构建MongoDB的$ expr,它类似于从Angular查询构建器模块获取的查询。由于RuleSet可以嵌套,因此您需要递归运行映射功能。下面的代码可能不会涵盖所有可能的情况,但是应该为您提供良好的入门入门。

let q = {
  "condition": "and",
  "rules": [
    {
      "field": "Brief_D_Reactiedatum",
      "operator": "!=",
      "value": "Eventtoets_Fn"
    },
    {
      "condition": "or",
      "rules": [
        {
          "field": "Alleen_AO",
          "operator": "=",
          "value": "Parkeerreden"
        }
      ]
    }
  ]
};

const conditions = { "and": "$and", "or": "$or" };
const operators = { "=": "$eq", "!=": "$ne", "<": "$lt", "<=": "$lte", ">": "$gt", ">=": "$gte" };

const mapRule = rule => ({
    [operators[rule.operator]]: [ "$"+rule.field, rule.value ]
});

const mapRuleSet = ruleSet => {
    return {
        [conditions[ruleSet.condition]]: ruleSet.rules.map(
            rule => rule.operator ? mapRule(rule) : mapRuleSet(rule)
        )
    }
};

let mongoDbQuery = { $expr: mapRuleSet(q) };
console.log(mongoDbQuery);
Run Code Online (Sandbox Code Playgroud)

结果表达式可以传递给MongoDB的find方法

db.col.find(mongoDbQuery);
Run Code Online (Sandbox Code Playgroud)

或进入$ match流水线阶段:

db.col.aggregate([{ $match: mongoDbQuery }]);
Run Code Online (Sandbox Code Playgroud)