Mongodb 如何使用Mongo聚合来限制给定输入的结果?

Mongodb 如何使用Mongo聚合来限制给定输入的结果?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我看了一遍,但没有看到如何做到这一点 假设您有一个用户,每个用户都有积分 User Points A 22 B 11 C 15 D 7 因此,我们使用'$sort':{points:-1}按点对用户进行排序 是否可以使用Mongo聚合阶段在给定用户之前和之后查找用户 因此,给定用户C(通过id),它将返回非常有趣的问题。也许有更好的解决办法 免责声明:我假设用户点是唯一的 我们可以使用来获得预期的结果,但成本很高(非常大的

我看了一遍,但没有看到如何做到这一点

假设您有一个用户,每个用户都有积分

User    Points
 A        22
 B        11
 C        15
 D         7
因此,我们使用
'$sort':{points:-1}
按点对用户进行排序

是否可以使用Mongo聚合阶段在给定用户之前和之后查找用户


因此,给定用户C(通过id),它将返回非常有趣的问题。也许有更好的解决办法

免责声明:我假设用户点是唯一的

我们可以使用来获得预期的结果,但成本很高(非常大的查询)


步骤:

  • 我们分为不同的领域:

    • 给定用户(C)
    • 按点数排序所有用户
    • 对所有点进行排序并存储在数组中(我希望MongoDB也允许按对象查找数组索引)
  • 现在我们找到给定的用户索引,计算“之前”/“之后”玩家的索引

  • 现在,我们用3个元素(before、current、after)创建结果


  • 注意:如果给定的用户是第一个/最后一个,我们确保在项目之前/之后返回
    null

    感谢您的帮助!是否可以插入索引ID(通过$project?),然后基于它进行限制?所以,在排序之后,元素将具有索引id:1、索引id:2等。我已经尝试过了,但没有成功。只有
    $unwind
    可以说是us array idx。但是如果知道用户
    C
    点,您可以计算精确的idx(
    db.collection.count({points:{$gt:15}}})
    ),然后使用以下方法:
    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"
          }
        ]
      }
    ]