在Mongo中存储/查询`last_read`的最佳方法是什么?

时间:2015-04-01 07:36:57

标签: node.js mongodb express mongoose

我正在使用MongoDB(通过Mongoose / Node),我正在尝试找出存储和查询last_read日期字段的最佳方法。我有一组帖子,每次访问者查看其中一个帖子时,我想存储时间戳。

此外,我想查询自当前用户的last_read时间戳以来已更新的任何帖子。

这似乎很标准,但我找不到多少。

对我来说,最简单的方法似乎是在Post上存储一个哈希,由访客ID键入,其值为Date。 Mongoose模式看起来像:

{
  title: String,
  created: Date,
  modified: Date,
  last_read: {} // Mixed
}

然后在加载帖子页面时,我正在运行:

var update = {};
update.last_read[req.user.id] = new Date();
Posts.findByIdAndUpdate(req.params.id, update, cb);

哪个有效,现在我的Post文档看起来像:

{
  title: 'My new post',
  created: 2015-04-01 06:25:53.094Z,
  modified: 2015-04-02 07:29:01.094Z
  last_read: {
    123userID456: 2015-04-01 06:25:53.094Z
  }
}

但我不确定如何查询最近修改过当前用户的last_read时间的帖子。我是否需要使用聚合管道?

我也是第二次猜测这种存储方法。起初它似乎是最简单的选项,但使用用户ID作为对象键的感觉是错误的。

感谢您的帮助。 :)

1 个答案:

答案 0 :(得分:1)

这不是你需要的类型混合的。

如果不改变保存数据的方法,您应该将Schema更改为以下内容:

{
  title: String,
  created: Date,
  modified: Date,
  last_read: [{
    _id: {
      type: Schema.Types.ObjectId,
      ref: 'user'
    },
    at: Date
  }]
}

使用此架构,您可以编辑阅读帖子的用户列表,如下所示:

// Add
post.last_read.push({
  _id: user.id,
  at: new Date()
});

// Find
var last_read = post.last_read.id(user.id);

// Edit
last_read.at = new Date();

// Save
post.save(callback);

有关子文档的更多信息,请查看Mongoose Documentation on topic

但我建议为此用例使用单独的集合。因为您要为特定用户阅读的帖子太多而有太多用户无法阅读特定帖子。大文档会导致MongoDB出现性能问题,而不仅仅是查询或编辑额外的集合。

{
  user: {
    type: Schema.Types.ObjectId,
    ref: 'user'
  },
  post: {
    type: Schema.Types.ObjectId,
    ref: 'post'
  },
  last_read: Date
}