mongo报错排查:can’t backfill array to larger than 1500000 elements
问题
这个报错是因为mongo在操作一个数组时是没有边界检测的,可以动态的往很大的下标插入一个数据,前面没有的元素默认填充为null
> db.test.insert({“field1":[]}); // 插入一个数据只有一个key value 为数组
WriteResult({ "nInserted" : 1 })
> db.test.findOne()
{ "_id" : ObjectId("5f7417c9bc8666768ec0b76c"), "field1" : [ ] }
> db.test.update({"_id":new ObjectId("5f7417c9bc8666768ec0b76c")}, {"$set":{“field1.10.content”:”test"}}) // 通过下标更新空数组
> db.test.findOne()
{
"_id" : ObjectId("5f7417c9bc8666768ec0b76c"),
"field1" : [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
{
"content" : "test"
}
]
}
但这个值不能大于1500000 否则就会报错
> db.test.insert({“field1":[]});
WriteResult({ "nInserted" : 1 })
> db.test.findOne()
{ "_id" : ObjectId("5f7417c9bc8666768ec0b76c"), "field1" : [ ] }
> db.test.update({"_id":new ObjectId("5f7417c9bc8666768ec0b76c")}, {"$set":{“field1.512649500.content”:”test"}})
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"writeError" : {
"code" : 15891,
"errmsg" : "can't backfill array to larger than 1,500,000 elements"
}
})
原因
在我的业务场景里field1这个字段 是 一个 key 为工单id 和 value 为工单内容,如果网络问题或对方服务问题工单id获取不到,就由于php是数组对象不分,空数组在mongo里是 []
正常应该是
{
"field1": {
512649500: { // 对象类型
"content": "test"
}
}
}
但由于网络等原因,这个id( 512649500)和 内容拿不到 就变成了
{
"field1": [] // 数组类型
}
于是更新的时候就悲剧了
解决
解决方案是 插入mongo前 吧 value 改成对象
$doc = [
"field1" => (object)$value,
];
$db.test.insert($doc);