mongodb - 获取最近的姓名、分数

标签 mongodb

我有一个 mongodb 集合,看起来像这样:

db.scores.insert({"name": "Bob", value: 96.3, timeStamp:'2010-9-27 9:32:00'})
db.scores.insert({"name": "John", value: 98.3, timeStamp:'2010-9-27 9:28:00'})
db.scores.insert({"name": "Bob", value: 99.3, timeStamp:'2010-9-27 9:29:00'})
db.scores.insert({"name": "John", value: 97.3, timeStamp:'2010-9-27 9:31:00'})

我如何查询这个以给我每个名字一次,以及最新的值:

{name: "John", value: 97.3}
{name: "Bob", value: 96.3}

最佳答案

您正在尝试进行数据聚合,因此您必须编写 map-reduce query .

映射

映射函数基本上是 SQL 中的 GROUP BY 子句。在您的情况下,我们将根据名称进行分组,因此我们将使用名称作为value 将包含我们需要的其他数据,在本例中为值和时间戳。

map = function () {
  emit(this.name, { timeStamp: this.timeStamp, value: this.value });
}

map 函数将为每个键生成一个值数组。因此,所有名为“Bob”的文档都映射到键“Bob”。对于您的示例数据,结果可能如下所示:

{ _id: "Bob", values: [
  { timeStamp: "2010-9-27 9:32:00", value: 96.3 },
  { timeStamp: "2010-9-27 9:29:00", value: 99.3 }
]},
{ _id: "John", values: [
  { timeStamp: "2010-9-27 9:28:00", value: 98.3 },
  { timeStamp: "2010-9-27 9:31:00", value: 97.3 }
]},

减少

reduce 函数负责将每个键的值数组减少为单个值。就您而言,我们只对具有最高时间戳的数据感兴趣:

reduce = function (key, values) {
  var maxData = { timeStamp: new Date(0) };

  values.forEach(function (data) {
    if (data.timeStamp > maxData.timeStamp) {
      maxData = data;
    }
  });

  return maxData;
}

请注意,reduce 函数的返回值与其接受的值具有相同的格式,这一点很重要。这是因为对于单个键,reduce 函数可能会被多次调用,每次只接受总值的一部分。

运行reduce函数将产生以下结果:

{ _id: "Bob", value: { timeStamp: "2010-9-27 9:32:00", value: 96.3 } },
{ _id: "John", value: { timeStamp: "2010-9-27 9:31:00", value: 97.3 } }

最终确定

终结器函数可用于仅提取我们需要的数据,即值。

finalize = function (key, value) {
  return value.value;
}

这将导致:

{ "_id" : "Bob", "value" : 96.3 },
{ "_id" : "John", "value" : 97.3 }

运行map-reduce

您可以使用这些函数运行映射缩减,如下所示:

res = db.scores.mapReduce(map, reduce, { finalize: finalize });

集合db[res.result]将包含查询结果。

最后一个问题

reduce 函数将时间戳与 Date objects 进行比较。从示例代码来看,您已将时间戳存储为字符串,而不是日期对象或整数时间戳。因此,在能够比较日期之前,您必须将这些字符串转换为 Date 对象。

关于mongodb - 获取最近的姓名、分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3805370/

相关文章:

java - Morphia 保存新实体而不是更新 _id

java - 如何在没有objectId的情况下使用spring-data mongodb进行更新插入?

mongodb - 如何在 MongoDB 的 $lookup 中返回单个对象而不是数组?

node.js - 使用 Mongoose 时 MongoDB 写入问题

node.js - docker : MongooseError [MongooseServerSelectionError]: getaddrinfo ENOTFOUND mongo

java - 玩 Morphia MongoDB : The type Filter is already defined

javascript - 无法在 find() 中设置和获取变量值

mongodb - 使用 let 变量的管道和 geoIntersect 查找

mongodb - 如何将 nitrous.io 框中的 mongodb 二进制文件更新为 2.4.x 版本?

mongodb - mongoexport 不会将任何记录写入 json 输出文件