【问题标题】:Mongodb: big data structureMongoDB:大数据结构
【发布时间】:2016-03-04 14:01:53
【问题描述】:

我正在重建我的网站,该网站是法国最活跃论坛的昵称搜索引擎:您搜索昵称并获得所有消息。

我当前的数据库包含超过 60Gb 的数据,存储在 MySQL 数据库中。我现在正在将它重写到一个 mongodb 数据库中,在检索到 100 万条消息(1 条消息 = 1 个文档)后 find() 开始需要一段时间。

文档的结构如下:

{
  "_id" : ObjectId(),
  "message": "<p>Hai guys</p>",
  "pseudo" : "mahnickname", //from a nickname (*pseudo* in my db)
  "ancre" : "774497928", //its id in the forum
  "datepost" : "30/11/2015 20:57:44"
}

我将 ID ancre 设置为唯一的,所以我不会得到两次相同的条目。

然后用户输入昵称,它会找到所有具有该昵称的文档。

这是请求:

Model.find({pseudo: "danickname"}).sort('-datepost').skip((r_page -1) * 20).limit(20).exec(function(err, bears)...

我应该采用不同的结构吗?我没有为每条消息创建一个文档,而是为每个昵称创建了一个文档,一旦我从该昵称收到一条新消息,我就会更新该文档?

我在 MySQL 中使用了第一种方法,但并没有花那么长时间。

编辑:或者我应该只索引昵称(pseudo)?

谢谢!

【问题讨论】:

  • 你应该给pseudo添加一个索引。在这里查看这篇文章,特别是选择性区域:stackoverflow.com/questions/33545339/…
  • 注意skip实际上必须解析它跳过的文档,所以如果r_page真的很大,那么skip将需要跳过一堆文档。
  • 啊哈,我完全忘记了为昵称编制索引。谢谢大佬,我现在试试
  • @DavidGrinberg r_page 可能真的很大,是的,这取决于昵称发布的消息。你有什么建议?
  • @Sinequanon 请参阅 Mongo 关于主题 here 的注释。另请查看是否可以添加更多数据进行过滤。加上索引。

标签: node.js mongodb data-structures mongoose database


【解决方案1】:

以下是针对您的大数据问题的一些建议:

  1. The ObjectId already contains a timestampYou can also sort on it。您可以通过删除 datepost 字段来节省一些磁盘空间。
  2. 您绝对需要ancre 字段吗? ObjectId 已经是唯一的并已编入索引。如果您绝对需要它并且还需要将 datepost 分开,您可以将 _id 字段替换为您的 ancre 字段。
  3. 正如许多人提到的,您应该在pseudo 上添加一个索引。这将使“获取伪名称为 mahnickname 的所有消息”的搜索速度更快。
  4. 如果每个用户的消息量很少,您可以将所有消息存储在每个用户的单个文档中。这将避免不得不跳到可能很慢的特定页面。但是,请注意16mb limit。我个人仍然会将它们放在多个文档中。
  5. 为保持快速查询速度,请确保您所有的indexed fields fit in RAM.您可以通过键入 db.collection.stats() 并查看 indexSizes 子文档来查看索引字段的 RAM 消耗。
  6. 是否有一种方法可以让您不跳过文档,而是将其写入数据库的时间用作您的页面?如果是这样,请使用datepost 字段或_id 中的时间戳作为您的分页策略。如果您决定使用datepost,请在pseudodatepost 上创建compound index

至于您的基准测试,您可以使用mongotopmongostat 密切监控MongoDB。

【讨论】:

    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 2012-02-18
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多