如何使用 mongodb 选择每个特定字段的记录数?

2023-11-29

我在 mongodb 中有一个文档集合,每个文档都有一个“组”字段,该字段引用拥有该文档的组。这些文件看起来像这样:

{
  group: <objectID>
  name: <string>
  contents: <string>
  date: <Date>
}

我想构建一个查询,返回每个组的最新 N 个文档。例如,假设有 5 个组,每个组有 20 个文档。我想编写一个查询,该查询将返回每个组的前 3 个文档,该查询将返回 15 个文档,每个组 3 个。每组得到 3 个,即使另一组有更新的第 4 个。

在 SQL 世界中,我相信这种类型的查询是通过“分区依据”和计数器完成的。 mongodb中有没有这样的事情,缺少对N个组进行N+1个单独的查询?


您还不能使用聚合框架来执行此操作 - 您可以获取每个组的 $max 或顶级日期值,但聚合框架还没有办法累积前 N 个,而且无法将整个文档推送到结果集中(仅限个别字段)。

所以你必须依靠 MapReduce。这是可行的,但我确信有很多变体(都需要以某种方式根据特定属性对对象数组进行排序,我从其中一个借用了我的解决方案这个问题的答案.

Map 函数 - 输出组名称作为键,文档的整个其余部分作为值 - 但它将其输出为包含数组的文档,因为我们将尝试累积每个组的结果数组:

map = function () { 
    emit(this.name, {a:[this]}); 
}

reduce 函数会将属于同一组的所有文档累积到一个数组中(通过 concat)。请注意,如果您通过检查日期来优化reduce以仅保留前五个数组元素,那么您将不需要finalize函数,并且在运行mapreduce期间将使用更少的内存(它也会更快)。

reduce = function (key, values) {
    result={a:[]};
    values.forEach( function(v) {
        result.a = v.a.concat(result.a);
    } );
    return result;
}

由于我保留每个键的所有值,因此我需要一个 Finalize 函数来仅提取每个键的最新五个元素。

final = function (key, value) {
      Array.prototype.sortByProp = function(p){
       return this.sort(function(a,b){
       return (a[p] < b[p]) ? 1 : (a[p] > b[p]) ? -1 : 0;
      });
    }

    value.a.sortByProp('date');
    return value.a.slice(0,5);
}

使用与您提供的模板文档类似的模板文档,通过调用 mapReduce 命令来运行它:

> db.top5.mapReduce(map, reduce, {finalize:final, out:{inline:1}})
{
    "results" : [
        {
            "_id" : "group1",
            "value" : [
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe13"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.498Z"),
                    "contents" : 0.23778377776034176
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe0e"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.467Z"),
                    "contents" : 0.4434165076818317
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe09"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.436Z"),
                    "contents" : 0.5935856597498059
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe04"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.405Z"),
                    "contents" : 0.3912118375301361
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfdff"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.372Z"),
                    "contents" : 0.221651989268139
                }
            ]
        },
        {
            "_id" : "group2",
            "value" : [
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe14"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.504Z"),
                    "contents" : 0.019611883210018277
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe0f"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.473Z"),
                    "contents" : 0.5670706110540777
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe0a"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.442Z"),
                    "contents" : 0.893193120136857
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe05"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.411Z"),
                    "contents" : 0.9496864483226091
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe00"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.378Z"),
                    "contents" : 0.013748752186074853
                }
            ]
        },
        {
            "_id" : "group3",
                        ...
                }
            ]
        }
    ],
    "timeMillis" : 15,
    "counts" : {
        "input" : 80,
        "emit" : 80,
        "reduce" : 5,
        "output" : 5
    },
    "ok" : 1,
}

每个结果都将 _id 作为组名称,将值作为该组名称集合中最近五个文档的数组。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 mongodb 选择每个特定字段的记录数? 的相关文章

随机推荐

  • 复制 Excel 单元格数据直到列中最近的填充单元格

    我是 Excel 的新手 我面临一些问题 我有一个 Excel 工作表 必须将其导入到我的另一个程序中 请考虑以下格式 Heading1 Sub heading1 Sub Sub heading1 Sub Sub heading2 Sub
  • Ruby 数组注入

    我试图使用注入方法记录 10 个线程的平均运行时间 但它给了我这个错误 undefined method for
  • 将文件从 URL 传输到 Cloud Storage

    我是一名 Ruby 开发人员 尝试使用 Python 编写的 Google Cloud Functions 但在将远程文件从给定 URL 传输到 Google Cloud Storage GCS 时遇到了困难 在等效的 RoR 应用程序中
  • 如何使用 android.mk 将 .aar 包含在 AOSP 中

    我需要在 aosp 构建树中使用 android mk 构建一个应用程序 我有一个自定义的 arr lib 它位于以下文件夹 apps libs mylib aar 中 任何人都可以告诉我如何将 aar 包含在 android aosp 构
  • 将“工作集”装入 MongoDB 的 RAM 意味着什么?

    MongoDB 很快 但前提是您的工作集或索引可以放入 RAM 那么 如果我的服务器有 16G RAM 这是否意味着我所有集合的大小都需要小于或等于 16G 如何说 好吧 这是我的工作集 其余的可以 存档 工作集 基本上是系统将处于活动状态
  • MVC模型验证

    因此 我当前正在构建一个需要用户模型验证的应用程序 如果向用户填写了不正确的属性 它会告诉他们 我已设置数据注释 但我不确定如何将错误消息转发回用户 到目前为止 我已经在我的模型和视图上进行了设置 Model public class Da
  • setNamedRange() 在电子表格容器之外?

    我已经尝试了尽可能多的组合 我的目标是让 Google Apps 脚本独立运行或从库中运行 并能够在电子表格中设置命名范围 据我所知 setNamedRange 方法仅在电子表格容器内可用 并且仅当您使用SpreadsheetApp get
  • Teams:Invoke-Webrequest 向 Teams 发送 base64 字符串 (png)

    我正在尝试将一个 png 格式的 base64 字符串发送到我们的团队频道 该频道具有 传入 Webhook 设置 消息已发送到频道 但没有显示图像 当我搜索此内容时 似乎无法将图像或任何其他类型的附件作为 base64 字符串发送到 Te
  • 在python中动态添加@property

    我知道我可以通过执行以下操作动态地将实例方法添加到对象 import types def my method self logic of method instance is some instance of some class inst
  • Win32 GUI 在调整大小时闪烁

    我有一个带有选项卡控件的 Win32 GUI 程序 每个选项卡都有一个列表视图控件 每当调整窗口大小时都会出现大量闪烁 我尝试过以下操作 在主 wndproc 中处理 WM ERASEBKGND 并返回 TRUE 没有效果 过滤掉事件循环中
  • 当UAC打开时,程序可以在没有管理员权限的情况下写入磁盘的根目录吗?

    如果我不是管理员并启动一个写入 C 某些文本文件的程序 在 Windows 7 或 Vista 中我是否需要管理员权限 我发现在 XP 中写入任何文件夹 包括 system32 都没有问题 但我不确定 NET 中的程序是否能够在没有管理员权
  • 与文本字段和日期选择器相关的问题

    我有一个与单击文本字段时隐藏和显示日期选择器视图相关的问题 实际上我有 2 个文本字段 这是我的问题图像 Problem 单击文本字段时日期选择器显示和隐藏 它应该在开始编辑时显示并在结束编辑时隐藏 当我们第一次点击 textfield 1
  • 在 LinearLayout 中动态创建多个 TextView

    我想创建多个TextView里面有一个LinearLayout 以下代码构建成功 但给出了NullPointerException在线上root addView t i public class MainActivity extends A
  • 创建通用 TypeScript 函数,为对象属性赋值

    我想创建一个简单的函数key特定对象的和value为相应的键并将新值分配给对象 像这样的东西 interface MyObject key1 string key2 number const object MyObject key1 abc
  • flex-grow 和 width 有什么区别?

    我最近开始使用 Flexbox 经常会出现需要在元素之间的主轴上分配空间的情况 我常常犹豫不决width and flex grow 例如 如果我希望一项测量 2 个测量 另一个测量 1 个测量 加起来为 100 我有两种选择 我可以设置w
  • UIScrollView 内的 UITextView 与 AutoLayout

    我试图将 UITextView 放置在带有 AutoLayout 的 UIScrollView 中 但没有成功 我尝试过的是 我将 UIScrollView 放置在 Storyboard 的主视图中 我将 UITextView 放置在 St
  • Libclang 的 python 绑定生成的 AST 无法解析 C++ 源代码中的某些标记

    我正在使用 Libclang 的 python 绑定 我基本上有两个疑问 我想知道我们如何解析既不是用户定义的也不是包含库的库函数 例如当我有以下源代码时 char a char malloc 4 Libclang 无法解析 malloc
  • 停止缓存 jQuery .load 响应

    我有以下代码对 URL 发出 GET 请求 searchButton click function inquiry load portal f searchBilling pid query val 但返回的结果并不总是能反映出来 例如 我
  • 当指针类型不同时如何生成编译错误?

    当两个指针 a 和 b 具有不同的基类型时 如何编写一个宏 CHECK a b 来生成编译错误 CHECK int 0 char 0 gt compilation error CHECK int 0 int 0 gt works 我正在寻找
  • 如何使用 mongodb 选择每个特定字段的记录数?

    我在 mongodb 中有一个文档集合 每个文档都有一个 组 字段 该字段引用拥有该文档的组 这些文件看起来像这样 group