【问题标题】:How to handle document size exceeds 16MB error while inserting a document into the collection on MongoDB如何在 MongoDB 上将文档插入集合时处理文档大小超过 16MB 的错误
【发布时间】:2018-01-04 10:50:12
【问题描述】:

在将文档插入 MongoDB 的集合时,任何人都可以建议如何处理文档大小超过 16MB 的错误。我得到了一些像 GridFS 这样的解决方案。通过使用 GridsFS 可以解决这个问题,但我需要一个不使用 GridFS 的解决方案。有什么方法可以使文档变小或拆分为子文档。如果是,我们如何实现?

from pymongo import MongoClient

conn = MongoClient("mongodb://sample_mongo:27017")
db_conn = conn["test"]
db_collection = db_conn["sample"]

# the size of record is 23MB

record = { \
    "name": "drugs",
    "collection_id": 23,
    "timestamp": 1515065002,
    "tokens": [], # contains list of strings
    "tokens_missing": [], # contains list of strings
    "token_mapping": {} # Dictionary contains transformed tokens
 }

db_collection.insert(record, check_keys=False)

我收到错误DocumentTooLarge:BSON 文档太大。在 MongoDB 中,最大 BSON 文档大小为 16 兆字节。

  File "/usr/local/lib/python2.7/dist-packages/pymongo-3.5.1-py2.7-linux-x86_64.egg/pymongo/collection.py", line 2501, in insert
check_keys, manipulate, write_concern)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-3.5.1-py2.7-linux-x86_64.egg/pymongo/collection.py", line 575, in _insert
check_keys, manipulate, write_concern, op_id, bypass_doc_val)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-3.5.1-py2.7-linux-x86_64.egg/pymongo/collection.py", line 556, in _insert_one
check_keys=check_keys)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-3.5.1-py2.7-linux-x86_64.egg/pymongo/pool.py", line 482, in command
self._raise_connection_failure(error)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-3.5.1-py2.7-linux-x86_64.egg/pymongo/pool.py", line 610, in _raise_connection_failure
raise error
  DocumentTooLarge: BSON document too large (22451007 bytes) - the connected server supports BSON document sizes up to 16793598 bytes.

【问题讨论】:

  • 欢迎来到Stack Overflow,请在提问时更具体一点:到目前为止,您对代码示例做了哪些尝试? (I downvoted because there is no code) / 您有什么期望? / 您会遇到什么错误? 请查看“How to ask”以获得帮助
  • Hille 更新了我尝试过的代码并指定了错误。谢谢。
  • 找出是什么文档字段使它如此之大(tokens、tokens_missing?),将其作为包含原始文档引用的文档存储在单独的集合中。

标签: mongodb python-2.7


【解决方案1】:

最大 BSON 文档大小为 16 兆字节。为了存储大于最大大小的文档,MongoDB 提供了GridFS API

GridFS 是用于存储和检索超过 BSON 文档大小限制 16 MB 的文件的规范。 GridFS 通过将大文件分成多个部分或块来存储它。每个块存储在一个单独的文档中。 GridFS 块的默认大小为 255 KB。 GridFS 使用两个集合来存储文件。一个集合存储文件块,另一个存储文件元数据。

【讨论】:

  • 不使用 GridFS 就不能处理这个问题吗?通过维护文档之间的引用,即将文档拆分为子文档,并通过文档之间的 ObejctIds 进行引用,从而减小文档大小。请让我知道你是否明白我的意思。我已经浏览了这个关于文档之间关系的 URL studytonight.com/mongodb/relationships-in-mongodb 但我不清楚如何实现。谢谢。
  • 您可以很好地将文档分成多个文档并将其存储在多个集合中,前提是每个文档的大小小于 16MB。 GridFS 是 mongoDB 提供的解决方案,用于存储更大尺寸的文档而无需手动拆分。无论哪种情况,文档都是手动拆分或通过 Mongo 拆分的。如果我们手动执行,我们需要维护文档之间的关系,而在 GridFS 中,它由 MongoDB 负责。对于 GridFS 示例,请参阅这篇文章 - api.mongodb.com/python/current/examples/gridfs.html
【解决方案2】:

快速回答是否定的,您无法绕过 16 MB BSON 大小限制。如果您达到此限制,您将需要探索替代方案,例如 GridFS 或为您的文档设计不同的架构。

我会首先提出一系列问题来确定您的设计重点,例如:

  1. 您有名为tokenstokens_missingtoken_mapping 的字段。我想这些字段单独很大,将所有三个字段放在一个文档中会将其推到 >16 MB。是否可以将此文档拆分为三个集合?

  2. 您的应用程序的访问模式是什么?您需要一直访问哪些字段?你不经常访问的领域是什么?您可以根据这些模式将文档拆分为不同的集合。

  3. 请记住对文档进行索引的必要性,因为 MongoDB 的性能与支持查询的良好索引高度相关。您不能在一个索引中索引两个数组。 Multikey Indexes有更多信息。

  4. 如果您需要在一个查询中合并所有相关数据,MongoDB 3.2 及更高版本为您提供$lookup operator,类似于 SQL 的左外连接。

与 SQL 的正常形式架构设计不同,MongoDB 的架构设计基于应用程序的访问模式。 16 MB 的限制是为了让您知道设计可能不是最佳的,因为如此大的文档会损害性能、难以更新等。通常,最好有很多小文档而不是少数巨大的文件。

更多示例请参见Data Model DesignData Model Examples and Patterns

【讨论】:

    猜你喜欢
    • 2018-09-11
    • 2020-11-19
    • 2013-02-24
    • 2020-11-18
    • 2020-08-17
    • 1970-01-01
    • 2013-01-02
    • 2018-12-15
    • 2016-02-22
    相关资源
    最近更新 更多