mongodb - 如何使用 Mongo 聚合来限制给定输入周围的结果?
问题描述
我查看了管道阶段文档,但没有看到如何执行此操作。
假设你有一个用户,每个用户都有积分。
User Points
A 22
B 11
C 15
D 7
因此,我们使用'$sort': { points: -1 }
按点对用户进行排序。
是否可以使用 Mongo 聚合阶段来查找给定用户之前和之后的用户?
因此,给定用户 C(按 id),它将返回[A, C, B]
.
解决方案
非常有趣的问题。也许存在任何更好的解决方案。
免责声明:我假设用户点是唯一的
我们可以使用$facet来获得预期的结果,但是成本很高(非常大的查询)
db.collection.aggregate([
{
$facet: {
"givenUser": [
{
$match: {
"user": "C"
}
}
],
"allUser": [
{
$sort: {
"Points": -1
}
}
],
"orderedPoints": [
{
$sort: {
"Points": -1
}
},
{
$group: {
_id: null,
Points: {
$push: "$Points"
}
}
},
{
$unwind: "$Points"
}
]
}
},
{
$project: {
allUser: 1,
currIndex: {
$indexOfArray: [
"$orderedPoints.Points",
{
$arrayElemAt: [
"$givenUser.Points",
0
]
}
]
},
beforeIndex: {
$add: [
{
$indexOfArray: [
"$orderedPoints.Points",
{
$arrayElemAt: [
"$givenUser.Points",
0
]
}
]
},
-1
]
},
afterIndex: {
$add: [
{
$indexOfArray: [
"$orderedPoints.Points",
{
$arrayElemAt: [
"$givenUser.Points",
0
]
}
]
},
1
]
}
}
},
{
$project: {
result: [
{
$arrayElemAt: [
"$allUser",
{
$cond: {
if: {
$lt: [
"$beforeIndex",
0
]
},
then: 999,
else: "$beforeIndex"
}
}
]
},
{
$arrayElemAt: [
"$allUser",
"$currIndex"
]
},
{
$arrayElemAt: [
"$allUser",
"$afterIndex"
]
}
]
}
}
])
[
{
"result": [
{
"Points": 22,
"_id": ObjectId("5a934e000102030405000000"),
"user": "A"
},
{
"Points": 15,
"_id": ObjectId("5a934e000102030405000002"),
"user": "C"
},
{
"Points": 11,
"_id": ObjectId("5a934e000102030405000001"),
"user": "B"
}
]
}
]
脚步:
我们保留在单独的字段中:
- 给定用户(C),
- 按点对所有用户排序
- 对所有点进行排序并存储在数组中(我希望 MongoDB 也允许按对象查找数组索引)
现在我们找到给定的用户索引,计算“之前”/“之后”玩家的索引。
现在,我们使用 3 个元素(之前、当前、之后)创建结果。
注意:如果给定的用户是第一个/最后一个,我们确保返回null
之前/之后的项目。
推荐阅读
- c# - angular c#更新多个可枚举模型
- python - pandas loc 不会为数据框增加价值
- ssl - 从 PEM 文件生成私钥
- css - 自定义的复选框看起来像一个按钮
- reporting-services - IIF 语句如果值为零,则跳过此并显示下一个值
- java - SQLite使用rowid删除行不起作用
- javascript - jQuery Slider 未在 Laravel 中显示动态图像
- windows - 创建文本并将其添加到 KODI .disc 文件的批处理
- python - Python3 与文件对象的兼容性
- python - 如何从内存中访问不规则形状数组中的项目?