带自数据的MongoDB条件查询
假设集合中有4个用户带自数据的MongoDB条件查询,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,假设集合中有4个用户 > db.users.find().pretty() { "_id" : ObjectId("5d369b451b48d91cba76c618"), "user_id" : 1, "final_score" : 65, "max_score" : 15, "min_score" : 15, } { "_id" : ObjectId("5d369b451b48d91cba76c619"), "user_id" :
> db.users.find().pretty()
{
"_id" : ObjectId("5d369b451b48d91cba76c618"),
"user_id" : 1,
"final_score" : 65,
"max_score" : 15,
"min_score" : 15,
}
{
"_id" : ObjectId("5d369b451b48d91cba76c619"),
"user_id" : 2,
"final_score" : 70,
"max_score" : 15,
"min_score" : 15,
}
{
"_id" : ObjectId("5d369b451b48d91cba76c61a"),
"user_id" : 3,
"final_score" : 60,
"max_score" : 15,
"min_score" : 15,
}
{
"_id" : ObjectId("5d369b451b48d91cba76c61b"),
"user_id" : 4,
"final_score" : 83,
"max_score" : 15,
"min_score" : 15,
}
我想提取满足以下条件的用户
=final\u score
的user\u id=3
+final\u score
每个文档的最大得分
这里的困难在于,您需要运行两个单独的管道(一个用于获取用户3的值,另一个用于过滤所有文档)。在聚合框架中,您可以使用运算符来实现这一点,该运算符允许您运行多个管道,然后在后续步骤中继续处理数据。要比较可以使用的数据并获得原始形状,需要使用和将嵌套数组转换为单独的文档final_score
根据您的描述,我想您已经知道
的分数是user3
在这种情况下:60
db.collection.aggregate([ { $addFields: { match: { $and: [ { $gte: [ "$final_score", { $subtract: [ 60, "$min_score" ] } ] }, { $lte: [ "$final_score", { $add: [ 60, "$max_score" ] } ] } ] } } }, { $match: { match: true } }, { $project: { match: 0 } } ])
正是我想要的。谢谢:)为了提高性能,我应该只在
字段上触发索引吗?@Hide不确定它是否能产生任何影响,您可以尝试使用和不使用index@Hide您可以通过索引final_score
以某种方式提高性能。您是否认识最终得分为user\u id
id=3的用户,或者只知道
?在任何情况下,都无所谓。(我可以单独查询)但我必须关注性能。user\u id
db.users.find({ 'final_score': { '$lte': '60 + this.max_score', '$gte': '60 - this.min_score' } })
db.users.aggregate([ { $facet: { user3: [ { $match: { user_id: 3 } } ], docs: [ { $match: {} } ] } }, { $addFields: { user3: { $arrayElemAt: [ "$user3", 0 ] } } }, { $project: { docs: { $filter: { input: "$docs", cond: { $and: [ { $lte: [ "$$this.final_score", { $add: [ "$user3.final_score", "$$this.max_score" ] } ] }, { $gte: [ "$$this.final_score", { $subtract: [ "$user3.final_score", "$$this.max_score" ] } ] }, ] } } } } }, { $unwind: "$docs" }, { $replaceRoot: { newRoot: "$docs" } } ])
db.collection.aggregate([ { $addFields: { match: { $and: [ { $gte: [ "$final_score", { $subtract: [ 60, "$min_score" ] } ] }, { $lte: [ "$final_score", { $add: [ 60, "$max_score" ] } ] } ] } } }, { $match: { match: true } }, { $project: { match: 0 } } ])