合并两个 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
}
}
])
我有两个 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
}
}
])