Node.js Mongo DB如何在两个数组中查找公共项,并在单个查询中按降序排序
这是我保存在数据库中的数据Node.js Mongo DB如何在两个数组中查找公共项,并在单个查询中按降序排序,node.js,mongodb,mongoose,aggregation-framework,Node.js,Mongodb,Mongoose,Aggregation Framework,这是我保存在数据库中的数据 0 _id:5e4d18bd10e5482eb623c6e4 name:'John singh', cars_owned:[ {car_id:'1'}, {car_id:'5'}, {car_id:'7'}, {car_id:'8'} ], 1 _id:5e4d18bd10e5482eb6g57f5rt name:'Josh kumar', cars_owned:[
0 _id:5e4d18bd10e5482eb623c6e4
name:'John singh',
cars_owned:[
{car_id:'1'},
{car_id:'5'},
{car_id:'7'},
{car_id:'8'}
],
1 _id:5e4d18bd10e5482eb6g57f5rt
name:'Josh kumar',
cars_owned:[
{car_id:'7'},
{car_id:'9'},
{car_id:'1'},
{car_id:'3'}
],
2 _id:5e4d18bd10e5482eb6r67222
name:'Jesse nigam',
cars_owned:[
{car_id:'6'},
{car_id:'7'},
{car_id:'9'},
{car_id:'3'}
],
3 _id:5e4d18bd10e5482eb6467ii46
name:'Jordan khan',
cars_owned:[
{car_id:'3'},
{car_id:'1'},
{car_id:'4'},
{car_id:'5'}
]
现在我想搜索一个起始名为“J”的用户,同时搜索我拥有的汽车,输入将是
'J',cars_owned['3','7','9','12','10']
1 _id:5e4d18bd10e5482eb6g57f5rt
name:'Josh kumar',
cars_owned:[
{car_id:'7'},
{car_id:'9'},
{car_id:'1'},
{car_id:'3'}
],
2 _id:5e4d18bd10e5482eb6r67222
name:'Jesse nigam',
cars_owned:[
{car_id:'6'},
{car_id:'7'},
{car_id:'9'},
{car_id:'3'}
],
0 _id:5e4d18bd10e5482eb623c6e4
name:'John singh',
cars_owned:[
{car_id:'1'},
{car_id:'5'},
{car_id:'7'},
{car_id:'8'}
],
3 _id:5e4d18bd10e5482eb6467ii46
name:'Jordan khan',
cars_owned:[
{car_id:'3'},
{car_id:'1'},
{car_id:'4'},
{car_id:'5'}
]
输出将是
'J',cars_owned['3','7','9','12','10']
1 _id:5e4d18bd10e5482eb6g57f5rt
name:'Josh kumar',
cars_owned:[
{car_id:'7'},
{car_id:'9'},
{car_id:'1'},
{car_id:'3'}
],
2 _id:5e4d18bd10e5482eb6r67222
name:'Jesse nigam',
cars_owned:[
{car_id:'6'},
{car_id:'7'},
{car_id:'9'},
{car_id:'3'}
],
0 _id:5e4d18bd10e5482eb623c6e4
name:'John singh',
cars_owned:[
{car_id:'1'},
{car_id:'5'},
{car_id:'7'},
{car_id:'8'}
],
3 _id:5e4d18bd10e5482eb6467ii46
name:'Jordan khan',
cars_owned:[
{car_id:'3'},
{car_id:'1'},
{car_id:'4'},
{car_id:'5'}
]
现在你会注意到结果是所有的用户,他们的名字以“J”开头,拥有的汽车在3,7,9,12,10中,但按降序排列,这就是拥有最多汽车的用户在顶部匹配,并与其他用户匹配。我希望在单个mongo db查询中根据匹配的最大汽车数对结果进行排序。到目前为止,我已经做了一个简单的find查询
User_data.find({name: { $regex: "^" + search_name },
cars_owned:{$elemMatch:{car_id:'3',car_id:'7',car_id:'9',car_id:'12',car_id:'10'}
}},function(err,resp){
console.log(JSON.stringify(resp,null,4));
});
但它只返回一个文档,我希望所有文档都具有给定的car_id,但按匹配的最大值排序。如果您不理解此问题中的任何内容,请随时在评论中提问,但请在单个mongo db查询中给出答案。我也可以使用聚合框架。提前感谢。您必须使用聚合。 首先定义列表中有多少用户的常用汽车,然后过滤匹配名称和至少一辆常用汽车的结果,最后按常用汽车对结果进行排序 问题是:
db.collection.aggregate([
{
$addFields: {
commonCars: {
$size: {
$setIntersection: [
[
"3",
"7",
"9",
"12",
"10"
],
"$cars_owned.car_id"
]
},
}
}
},
{
$match: {
$expr: {
$and: [
{
$eq: [
{
$regexMatch: {
input: "$name",
regex: "^J"
}
},
true
]
},
{
$gt: [
"$commonCars",
0
]
}
]
}
}
},
{
$sort: {
"commonCars": -1
}
}
])
编辑 如果您不需要对结果进行排序,您可以在一个匹配阶段实现这一点:
db.collection.aggregate([
{
$match: {
$expr: {
$and: [
{
$eq: [
{
$regexMatch: {
input: "$name",
regex: "^J"
}
},
true
]
},
{
$gt: [
{
$size: {
$setIntersection: [
[
"3",
"7",
"9",
"12",
"10"
],
"$cars_owned.car_id"
]
},
},
0
]
}
]
}
}
},
])
答案就是这样,但我想同时搜索姓名和普通汽车。在您的回答中,首先扫描所有文档以查找普通汽车,然后在其中获取名称。我也不想搜索名称,然后查找常见的车辆,我想同时(总共)搜索这两种车辆。您可以在匹配阶段执行$setcrossion操作,但在这种情况下,您将无法执行$sort操作,因为setcrossion结果的大小将仅为$match阶段计算。要执行排序,您必须添加。。。这个$addFields阶段。你能给我一个问题吗?我想得到这个答案。我把它添加到我以前的答案中。我的问题解决了,我已经接受了答案。谢谢。