如何在Mongoose中获得文档的中间部分?

集合架构:

{
  _id: string,
  points: number
}

我想要按点排序,然后按_id匹配,最终结果获取前50名和后50名,Matched_id为中心.还包括基于排序的索引将很好,但不是必要的.

推荐答案

从MongoDB版本5.0开始,一种 Select 是使用$setWindowFields:

db.collection.aggregate([
  {$setWindowFields: {
      sortBy: {points: -1},
      output: {
        neighbors: {
          $push: "$$ROOT",
          window: {documents: [-N, N]}
        }
      }
  }},
  {$match: {_id: _id}},
  {$project: {neighbors: 1, _id: 0}},
  {$unwind: {path: "$neighbors", includeArrayIndex: "index"}},
  {$project: {
      _id: "$neighbors._id",
      points: "$neighbors.points",
      index: 1
  }}
])

看看它在playground example号公路上是如何工作的

  • 如果文档很重,或者N是一个大数字,您可以只按下_id,然后在$match之后使用$lookup

EDIT:如果您想要根据整个排序进行索引:

  1. $setWindowFields上添加另一个输出字段以设置索引
  2. 使用$reduce设置为我们使用的所有项目编制索引
db.collection.aggregate([
  {$setWindowFields: {
      sortBy: {points: -1},
      output: {
        neighbors: {
          $push: "$$ROOT",
          window: {documents: [-N, N]}
        },
        index: {
          $sum: 1,
          window: {documents: ["unbounded", "current"]}
        }
      }
  }},
  {$match: {_id: _id}},
  {$project: {
      neighbors: {$reduce: {
          input: "$neighbors",
          initialValue: [],
          in: {$concatArrays: [
              "$$value",
              [{$mergeObjects: [
                    "$$this",
                    {index: {$add: [{$subtract: [{$size: "$$value"}, N + 1]}, "$index"]}}
              ]}]
          ]}
      }},
      _id: 0
  }},
  {$unwind: "$neighbors"},
  {$replaceRoot: {newRoot: "$neighbors"}}
])

看看它在playground example号公路上是如何工作的

Node.js相关问答推荐

使用OpenAI API时遇到问题

当变量在另一个文件中初始化时,在初始化错误之前无法访问变量

try 插入重复的邮箱时,mongoDB DuplicateKey 错误未定义

在 NodeJS 中使用 post 时出现错误 500TypeError: 无法解构 'req.body' 的属性 'name',因为它未定义

DynamoDB 分页数据检索

如何在 Docker 容器中 SSO 登录 AWS(使用 aws-sdk v3)

(Mongoose) 删除 TTL 字段失败

在express js模型中将js转换为Typescript 时Typescript 错误

Azure Function 在 2022 年 4 月 26 日禁用将用户字段设置为 HTTP 请求对象

NodeJs 过滤掉目录异步

Web3.js 脚本在监听 CreatedPairs 时退出

我们如何或可以通过 npm 和 Meteor 使用 node 模块?

如何使用适用于 Node.js 的 AWS 开发工具包将 Amazon S3 中的所有对象从一个前缀复制/移动到另一个前缀

使用 Socket.io 将客户端连接到服务器

Connect/Express 中的session和cookieSession中间件有什么区别?

安装Node.js 安装n 安装Node.js?

处理快速异步中间件中的错误

Node.js - 判断是否安装了模块而不实际需要它

如何在 NodeJS 中拆分和修改字符串?

'node' 未被识别为内部或外部命令