mongodb:具有最大匹配目标数的文档
我需要帮助来解决以下问题。我的收藏有一个“目标”字段 每个用户可以有0个或多个目标 当我运行查询时,我希望检索具有最大匹配目标数的文档 例:mongodb:具有最大匹配目标数的文档,mongodb,mongoose,mongodb-query,aggregation-framework,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我需要帮助来解决以下问题。我的收藏有一个“目标”字段 每个用户可以有0个或多个目标 当我运行查询时,我希望检索具有最大匹配目标数的文档 例: 您似乎要求返回满足最多条件的文档,可能不是所有条件。基本过程是一个$或查询,以返回可以匹配任一条件的文档。然后,您基本上需要一个语句来计算文档中满足了“多少条件”,并返回匹配最多的条件 因此,这里的组合是一个语句,它使用的初始结果用于计算结果,然后对结果进行排序: //初始目标对象 var userTarget={ “集群”:“01”, “环境”:“DC”
您似乎要求返回满足最多条件的文档,可能不是所有条件。基本过程是一个
$或
查询,以返回可以匹配任一条件的文档。然后,您基本上需要一个语句来计算文档中满足了“多少条件”,并返回匹配最多的条件
因此,这里的组合是一个语句,它使用的初始结果用于计算结果,然后对结果进行排序:
//初始目标对象
var userTarget={
“集群”:“01”,
“环境”:“DC”,
“核心”:“PO”
};
//转换成美元或条件
//与计算条件相匹配
变量或条件=[],
scoreCondition=[]
key(userTarget).forEach(function(key){
var query={},
cond={“$cond”:[{“$eq”:[“$target.”+key,userTarget[key]]},1,0]};
查询[“target.+key]=userTarget[key];
orCondition.push(查询);
计分条件推(秒);
});
//运行聚合
模型集料(
[
//符合条件
{“$match”:{“$or”:或条件},
//根据匹配字段计算“分数”
{“$project”:{
"目标":一,,
“分数”:{
“$add”:计分条件
}
}},
//按最大“分数”排序(降序)
{“$sort”:{“score”:-1},
//返回第一个文档
{“$limit”:1}
],
函数(错误、结果){
//检查错误
//记住,结果是一个数组,即使仅限于一个文档
console.log(结果[0]);
}
)
因此,在处理聚合语句之前,我们将根据userTarget
对象中的输入生成管道操作的动态部分。这将产生一个或条件
,如下所示:
{“$match”:{
“$or”:[
{“target.cluster”:“01”},
{“target.env”:“DC”},
{“target.core”:“PO”}
]
}}
而scoreCondition
将扩展为如下编码:
“分数”:{
“$add”:[
{“$cond”:[{“$eq”:[“$target.cluster”,“01”]},1,0]},
{“$cond”:[{“$eq”:[“$target.env”,“DC”]},1,0]},
{“$cond”:[{“$eq”:[“$target.core”,“PO”]},1,0]},
]
}
这些将用于选择可能的文档,然后计算可能匹配的术语。具体而言,“分数”是通过评估三元运算符内的每个条件得出的,然后在有匹配项的情况下归因于1
,或者在该字段上没有匹配项的情况下归因于0
如果需要,可以很简单地改变逻辑,为每个字段分配更高的“权重”,并根据比赛的重要性向分数方向分配不同的值。无论如何,您只需将每个字段的这些分数结果合并在一起即可获得总体“分数”
然后,只需对返回的“score”应用,然后使用返回顶部文档即可
这不是超高效的,因为即使这三个条件都匹配,但您对数据提出的基本问题不能假定存在,因此它需要查看“至少一个”条件匹配的所有数据,然后根据这些可能的结果计算出“最佳匹配”
理想情况下,我个人会“首先”运行一个额外的查询,以查看是否所有三个条件都满足,如果不满足,则查找其他情况。这仍然是两个独立的查询,不同于仅仅将所有字段的“and”条件作为$或中的第一条语句
因此,我认为首选的实施方式应该是:
查找与所有给定字段值匹配的文档;如果没有,那么
在每个字段上运行或,并计算条件匹配数
这样,如果所有字段都匹配,则第一个查询速度最快,如果没有实际结果,只需返回清单中显示的较慢但必需的实现。您似乎要求返回满足最多条件的文档,可能不是所有条件。基本过程是一个$或
查询,以返回可以匹配任一条件的文档。然后,您基本上需要一个语句来计算文档中满足了“多少条件”,并返回匹配最多的条件
因此,这里的组合是一个语句,它使用的初始结果用于计算结果,然后对结果进行排序:
//初始目标对象
var userTarget={
“集群”:“01”,
“环境”:“DC”,
“核心”:“PO”
};
//转换成美元或条件
//与计算条件相匹配
变量或条件=[],
scoreCondition=[]
key(userTarget).forEach(function(key){
var query={},
cond={“$cond”:[{“$eq”:[“$target.”+key,userTarget[key]]},1,0]};
查询[“target.+key]=userTarget[key];
orCondition.push(查询);
计分条件推(秒);
});
//运行聚合
模型集料(
[
//符合条件
{“$match”:{“$or”:或条件},
//根据匹配字段计算“分数”
{“$project”:{
"目标":一,,
“分数”:{
“$add”:计分条件
}
}},
//按最大“分数”排序(降序)
{“$sort”:{“score”:-1},
//返回第一个文档
{“$limit”:1}
],
函数(err,res
documents=[{
targets:{
"cluster":"01",
}
},{
targets:{
"cluster":"01",
"env":"DC",
"core":"PO"
}
},{
targets:{
"cluster":"01",
"env":"DC",
"core":"PO",
"platform":"IG"
}
}];
userTarget={
"cluster":"01",
"env":"DC",
"core":"PO"
}