【问题标题】:What's the best way to store references to a gridFS file in a document?在文档中存储对 gridFS 文件的引用的最佳方法是什么?
【发布时间】:2012-02-18 01:33:35
【问题描述】:

我正在使用 MongoDB 存储用户配置文件,现在我想使用 GridFS 为每个配置文件存储一张图片。

我比较链接两个文档的两种方式是:

A) 在用户的image 字段中存储对文件 ID 的引用:

User: 
{
  "_id": ObjectId('[user_id here]'),
  "username": 'myusername',
  "image": ObjectId('[file_id here]')
}

B) 在文件的元数据中存储对用户的引用:

File metadata: 
{
  "user_id": ObjectId('[user_id here]')
}

我知道在很多方面这取决于我并且取决于应用程序的细节(它将是移动的,如果有帮助的话),但我只是想知道这样做是否有任何普遍的好处还是其他?

【问题讨论】:

    标签: mongodb gridfs


    【解决方案1】:

    这里的答案实际上取决于您的应用程序的使用模式。我的假设(请随时纠正我)是最可能的模式是这样的:

    查找用户 --> 查找用户 --> 显示配置文件(获取图片)

    在这个通用用例中,使用方法 A,您可以找到包含图像对象 ID 的用户文档,以显示配置文件,然后您随后使用该 ID 获取文件(2 个基本操作,您就完成了)。

    注意:从 GridFS 实际获取文件我将其视为单个逻辑操作,实际上涉及多个操作,但大多数驱动程序/API 无论如何都掩盖了这一点。

    使用方法 B,您将不得不找到用户文档,然后执行另一个查询以在文件元数据集合中找到相关的 user_id,然后去获取文件。据我计算,这是三个操作(方法 A 没有的额外发现)。

    这有意义吗?

    当然,如果我的假设不正确并且您的应用程序是(例如)图像驱动的,那么您的查询模式可能会得出不同的答案。

    【讨论】:

    • 谢谢——你能澄清一下吗?我假设使用方法 B 我可以 1) 获取用户,以及 2) 获取包含具有先前检索到的用户的用户 ID 的元数据的文件。我没有文件元数据的经验,所以这个细节是错误的,但我在想象像 $grid->findOne(array('metadata'=>array('user_id'=>ObjectId('[user_id这里]'))))(使用 PHP 驱动程序).. 这不可能吗?
    • 当你提到元数据时,我以为你指的是一个单独的集合,而不是 GridFS 使用的文件集合 - 默认情况下不包含 user_id,所以我在我的头。当然,您可以将 user_id 添加到文件集合中,这样您就可以直接查询它。在这种情况下,您必须确保正确索引文件集合以针对您的查询优化它,而不是使用“标准”GridFS 设置 - 让您记住更多但同样有效。结果我仍然会选择方法 A,但取决于你:)
    • 感谢您的帮助!
    • Matt/Adam,很抱歉打扰了这个帖子。我有同样的问题,但我也想知道如何在每个循环中检索所有用户的列表并同时显示他们的图像。我是否应该简单地按照选项 A(主帖的)然后在每个用户的用户对象中放置一个输入流?
    猜你喜欢
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2010-11-24
    相关资源
    最近更新 更多