合并两个 mongodb 查找并聚合为一个

Consolidate two mongodb find and aggregate into one

我有两个 mongoDB 查询,一个是聚合查询,另一个是查找查询。 它们的编码方式是,如果“聚合”查询给出结果,则“查找”查询不会 运行,否则,如果“聚合”不给出结果,则查找查询 运行。 通过以下方式:-

var pipeline1 = [{
      $match: { "user_id": "123" } //dynamic value based on request
    }, {
      $lookup: {
        from: "config_rules",
        localField: "group_id",
        foreignField: "rule_type_value", //this field has group id mapped || or can be null
        as: "rule"
      }
    },
    {
      $unwind: "$rule"
    },{
      $match:{ "rule.configtype": "profile" } //dynamic value based on request
    }];
db.getCollection("user_group_mapping").aggregate(pipeline);

如果上面的聚合给出了一个结果,那么同样是returned。否则我们 运行 下面的查找查询来获取普通用户的配置规则,并且 return 它

var query = {
    $and: [
        { rule_type_value: null }, //null for general user rules
        { configtype: "profile" }
    ]
}
db.getCollection("config_rules").find(query)

简单来说,对于一个请求,我们检查请求者是否在一个组中,如果是,那么我们return根据这个组配置规则, 如果请求者不在任何组中,那么我们 return 一般配置规则。

所以我的查询如上所示,这是针对不同集合的两个不同查询 运行,需要两个单独的 mongo 调用。我能以某种方式将这些查询组合成 1 个查询吗? 喜欢 - 如果对于给定用户,他在组 return 组特定配置或 return 通用配置规则中。

我想结合这些,这样在我的代码中我将只需要进行一次数据库调用(这个数据库调用本身将两个查询合并为一个)而不是两个。

user_group_mapping 集合中的示例文档

{  "user_id": "123",
   "group_id": "beta_users"
},
{  "user_id": "213",
   "group_id": "alpha_testers";
}

config_rules 中的示例数据:

{  "rule_type_value":"beta_users",
   "configType": "help",
   "configVersion": "1.1"
},
{  "rule_type_value":null,
   "configType": "help",
   "configVersion": "1.0"
},
{  "rule_type_value":"alpha_testers",
   "configType": "help",
   "configVersion": "1.3"
}

示例输入:

请求 1 user_id:“123” 配置类型:“帮助”

请求 2 user_id:“678” 配置类型:“帮助”

示例输出:(为了简单起见,我只写了规则内容)

请求 1 配置 v1.1 将 returned

{  "rule_type_value":"beta_users",
   "configType": "help",
   "configVersion": "1.1"
}

Req 2 v1.0 将 returned

{  "rule_type_value":null,
   "configType": "help",
   "configVersion": "1.0"
}

MongoDB聚合没有流量控制,如果一个阶段没有文档输出,则不会执行后续阶段。

如果您想从链接集合中检索 2 个可能值中的 1 个,请更改 $lookup 阶段以便选择所有可能的文档,然后过滤返回的列表。也许类似于:

[
  {$match: { "user_id": "123" }}, 
  {$lookup: {
        from: "config_rules",
        let: {targetgroup: "$group_id"},
        pipeline: [{$match:{
           configtype: "profile",
           $or:[
             {$expr:{$eq:["$rule_type_value","$$targetgroup"]}},
             { rule_type_value: null,  }
           ]
        }}],
        as: "rule"
  }},
  {$set: {
     rule: {$cond: {
       if: {$in: ["$group_id", "$rule.rule_type_value"]},
       then: {$filter: {
                 input: "$rule",
                 cond: {$eq: ["$group_id", "$$this.rule_type_value"]}
       }},
       else: "$rule"
  }},

尝试:

https://mongoplayground.net/p/m3HxBQIuqpS

  • 请在第23行设置configType并在第31行设置user_id
db.config_rules.aggregate([
  {
    $lookup: {
      from: "user_group_mapping",
      localField: "rule_type_value",
      foreignField: "group_id",
      as: "rule"
    }
  },
  {
    $addFields: {
      "ruleCount": {
        $size: "$rule",
      },
      "user_id": {
        $first: "$rule.user_id"
      }
    }
  },
  {
    $match: {
      "configType": "help"
    }
  },
  {
    $match: {
      $or: [
        {
          user_id: {
            $eq: "678"//123 or 678
          }
        },
        {
          user_id: {
            $exists: false
          }
        }
      ]
    }
  },
  {
    $sort: {
      "ruleCount": -1
    }
  },
  {
    $limit: 1
  },
  {
    $project: {
      "_id": 0,
      "rule_type_value": 1,
      "configType": 1,
      "configVersion": 1
    }
  }
])