1

所以,我遇到了一个问题。我有一个服务器正在尝试根据提供的数据生成“漂亮”的 URL。为了讨论,让我们说博客文章的标题。这个 url 显然需要是唯一的,以正确表示资源。好吧,如果我错了,请纠正我。但这在 MongoDB 中不是一个简单的问题吗?

起初我用谷歌搜索了某种类型的自动递增字段。这返回了我的预期,但有一个明显的问题.. 10gen 建议不要这样做。

警告 通常在 MongoDB 中,您不会对 _id 字段或任何字段使用自动增量模式,因为它不适用于具有大量文档的数据库。通常,默认值 ObjectId 更适合 _id。

注意加粗的文本。10gen 不建议您增加任何字段。

所以,回到问题上来。如果我给服务器一个帖子标题,并且我希望它创建一个帖子,我希望它会自动将我的标题更改为一个唯一的标题。例如,如果我创建三个标题为 的帖子foo,我希望服务器为/foo/foo1/foo2. 虽然,它可以是任何形式的唯一添加,这里的重点是服务器正在处理创建唯一 url 的肮脏工作,而不是简单地失败并让用户反复尝试提出唯一 url。

话虽如此,这是如何以“MongoDB方式”完成的?10gen 建议不要增加,基本上我能找到的唯一唯一字符串是ObjectID,但/foo50bbe1573b60ff0000000002几乎不是“漂亮”。你不得不承认,如果你被迫使用/foo50bbe1573b60ff0000000002,你还不如直接使用/50bbe1573b60ff0000000002. “漂亮”在前 5 个字符之后早已不复存在。

那么,关于如何以 MongoDB 友好的方式处理这个问题有什么想法/意见吗?

可能的答案: 一个可怕的解决方案是重复文档创建直到唯一的通过,但最多 X 次。例如,

  1. 你可以试着用标题写
  2. 如果失败,用标题加上 objectid 的增量值(比如 00002)写入它
  3. 如果失败了,就用整个该死的objectid来写吧。无论如何,我们已经输了。

可能的答案: 另一个可能的答案,就是按照 10gen 的建议去做,做一个递增的字段。

在上述两种解决方案中,我确信每种方法在不同的方法上都更有效。例如:如果您的唯一字段很可能是唯一的,例如 40 个用户输入的数据字符,则解决方案 1 可能是最好的。如果你处理 4 个字符,它可能会像糖蜜一样慢。

编辑:更好的答案 我认为两者的结合是最好的。拥有一组“原始”网址(例如/foo:),并计算它们被写入的次数。将计数附加到您的目标网址,您就有了一个唯一的网址。我相信这将是 10gen 建议反对的性能问题之间的平衡,同时仍然为您提供增量。

4

1 回答 1

4

10gen 警告不要放置某种悲观并发或使用服务器端 javascript 来查找 ENTIRE 集合的当前最大键,然后递增它并返回新的 _id。MongoDB 是为通常依赖于火而忘记插入/更新的大型集合而设计的。根据您所描述的应用程序的性质,这些都不是障碍(比 10gen 的建议更重要的是您对问题域的了解以及这可能如何与他们向您发出警告的项目交互)。

一个不违背 10gen 建议的更好方案是从帖子的其他一些属性(即用户名、创建日期和时间等)中构建一个 url。

在您的博客文章示例中,您的 url 路径可能看起来像

/posts/userName/2013/3/5/title-of-my-post

您必须根据所显示资源的属性来决定实际方案,但这是一个好的开始。在此示例中,除非单个用户在同一天创建两个标题完全相同的帖子,否则确保唯一的 url 不会有问题。在这种情况下,您的文档可能如下所示:

{ _id: ObjectId(...), userName: "userName", dateCreated: ISODate("2013-03-05"), title: "我的帖子标题", body: "..." }

使用唯一索引{dateCreated: -1, userName: 1, title: 1}(这也可以让您很好地按用户对帖子进行排序和排序)。

于 2013-03-06T01:57:54.277 回答