不能回填大于1500000个元素的数组

Can't backfill array to larger than 1500000 elements

本文关键字:元素 数组 1500000个 大于 不能      更新时间:2023-09-26

我有一个mongodb文档命名为collection:

{
    _id: ObjectId('53e9dd54c784717558c46997'),
    bloks: [ /* subdocument array */ ],
    sections: [ /* subdocument array */ ],
    chapters: [ /* subdocument array */ ]
} 

和每个子文档都有idstate字段作为其他字段之间的字符串。

当使用mongoose时,我可以更新bloks并使用

返回集合:
update = { bloks: [ /*some changed array*/ ] };
Collection.findByIdAndUpdate(collection._id, update, function (err, collection) {
    if (err) {
        // return an error
    } else {
       // return the collection
    }
});

但是当我尝试在其他数组中更新特定的section和chapter状态时:

update = { 
    bloks: [ /*some changed array*/ ],
    'sections.140439739188823467.state': 'some state',
    'chapters.1404397391757313579.state': 'some state'
};

我得到一个错误:

Can't backfill array to larger than 1500000 elements

我如何更新集合文档与块,节和章节的数据,并有它的当前值?

请注意,我使用.findByIdAndUpdate(),因为它更有效,我有问题,使.update()方法做实际保存。

感谢Leonid Beschastny在问题中的评论,我发现我正在使用子文档id作为数组中的索引,因此我修改了代码以找出正确的。

    sindex = _.findIndex(collection.sections, function (section) {
        return sid === section.id;
    });
    if (-1 < sindex) {
        update['sections.' + sindex + '.state'] = 'state';
    }

    hindex = _.findIndex(collection.chapters, function (chapter) {
        return hid === chapter.id;
    });
    if (-1 < hindex) {
        update['chapters.' + hindex + '.state'] = 'state';
    }

实际上,有一种方法可以通过其id更新子文档的字段,使用位置操作符$:

db.collection.update({
    _id: collection._id,
    'sections.id': '140439739188823467'
}, {
    'sections.$.state': 'some state'
});

这种方法的唯一问题是不能使用单个查询更新多个子文档。因此,它需要两个请求来更新sectionschapters


您还应该考虑使用mongoose子文档特性。在现有的模式中,您唯一需要更改的是子文档的主id字段,因为mongoose总是使用_id字段作为主标识符。

它将允许您使用MongooseDocumentArray::id helper,特别为您的情况设计:

sindex = collection.sections.id(sid);
hindex = collection.sections.id(hid);

还有一件事。

因为你已经抓取你的文档,没有必要你发出一个findAndModify操作,因为当你调用.save()方法在mongoose文档它发出update操作,发送到MongoDB只更新字段:

collcetion[sindex].state = 'new state';
collcetion[hindex].state = 'new state';
collcetion.save(next);
// Mongoose sends update operation, setting only this two fields

此外,mongoose使用版本控制来确保子文档数组中文档的顺序没有改变,从而保护您不会更新错误的子文档。