MongoDB、Python 和 PyMongo:文档大小太大且 BSONObj 大小无效
MongoDB, Python and PyMongo: Document size too large with BSONObj size is invalid
写入 Mongo 时出现此错误:
OperationalFailure caught
10334
{u'connectionId': 2365, u'code': 10334, u'ok': 1.0, u'err': u'BSONObj size: 17254820 (0xA4490701) is invalid. Size must be between 0 and 16793600(16MB) First element: 0:
这是一个充满字符串和整数的普通文档,在 Python 中构建,但它的大小似乎是 17,25MB。你会怎么做?
数据是这样的:
{ date: new Date(1417996800000),
visitors: [ { owner: "AS3320 Deutsche Telekom AG", ip: "82.148.15.23", views: 844 },
{ owner: "AS29314 VECTRA S.A.", ip: "173.235.42.25", views: 458 },
...
]
}
那个数组中有很多很多元素,但我很惊讶数量超过了 16MB。
将数组的大小限制为 8500 个元素后,出现此 PyMongo 错误:
$ operator made object too large
我的文档过大而且我的架构很糟糕,显然,另请参阅:Mongodb update with upsert fails
在设计 Mongo 模式时需要考虑很多事情,但通常模式应该反映您使用数据的方式。 MongoDB 博客上的 6 Rules of Thumb for MongoDB Schema Design 文章系列是一个好的开始。
我的第一个想法是将您的文档"inside out" 并存储在一个集合中:
{ date: new Date(1417996800000), owner: "AS3320 Deutsche Telekom AG", ip: "82.148.15.23", views: 844 },
{ date: new Date(1417996800000), owner: "AS29314 VECTRA S.A.", ip: "173.235.42.25", views: 458 },
...
这样您就不会限制每天可以拥有多少唯一用户。如果您在 date
字段上建立索引,按日期查找访问者仍然很有效。
如果您不经常使用 owner
字段,或许也可以将其移至自己的集合中。
{ ip: "82.148.15.23", owner: "AS3320 Deutsche Telekom AG"},
{ ip: "173.235.42.25", owner: "AS29314 VECTRA S.A."},
...
显然,这不是一个明确的答案,但这可能是一个开始。
关于在写入之前检查文档的大小(我认为这不是解决糟糕的架构设计的好方法)。数据由 MongoDB 在内部作为 BSON 处理,因此您可以使用 bson
module:
import bson
len(bson.dumps(my_document))
如果您收到 "operator made object too large" 错误,请参阅 this question。
写入 Mongo 时出现此错误:
OperationalFailure caught
10334
{u'connectionId': 2365, u'code': 10334, u'ok': 1.0, u'err': u'BSONObj size: 17254820 (0xA4490701) is invalid. Size must be between 0 and 16793600(16MB) First element: 0:
这是一个充满字符串和整数的普通文档,在 Python 中构建,但它的大小似乎是 17,25MB。你会怎么做?
数据是这样的:
{ date: new Date(1417996800000),
visitors: [ { owner: "AS3320 Deutsche Telekom AG", ip: "82.148.15.23", views: 844 },
{ owner: "AS29314 VECTRA S.A.", ip: "173.235.42.25", views: 458 },
...
]
}
那个数组中有很多很多元素,但我很惊讶数量超过了 16MB。
将数组的大小限制为 8500 个元素后,出现此 PyMongo 错误:
$ operator made object too large
我的文档过大而且我的架构很糟糕,显然,另请参阅:Mongodb update with upsert fails
在设计 Mongo 模式时需要考虑很多事情,但通常模式应该反映您使用数据的方式。 MongoDB 博客上的 6 Rules of Thumb for MongoDB Schema Design 文章系列是一个好的开始。
我的第一个想法是将您的文档"inside out" 并存储在一个集合中:
{ date: new Date(1417996800000), owner: "AS3320 Deutsche Telekom AG", ip: "82.148.15.23", views: 844 },
{ date: new Date(1417996800000), owner: "AS29314 VECTRA S.A.", ip: "173.235.42.25", views: 458 },
...
这样您就不会限制每天可以拥有多少唯一用户。如果您在 date
字段上建立索引,按日期查找访问者仍然很有效。
如果您不经常使用 owner
字段,或许也可以将其移至自己的集合中。
{ ip: "82.148.15.23", owner: "AS3320 Deutsche Telekom AG"},
{ ip: "173.235.42.25", owner: "AS29314 VECTRA S.A."},
...
显然,这不是一个明确的答案,但这可能是一个开始。
关于在写入之前检查文档的大小(我认为这不是解决糟糕的架构设计的好方法)。数据由 MongoDB 在内部作为 BSON 处理,因此您可以使用 bson
module:
import bson
len(bson.dumps(my_document))
如果您收到 "operator made object too large" 错误,请参阅 this question。