使用MongoDB 2.6.12更新深度嵌入的文档

时间:2018-07-19 15:17:31

标签: node.js mongodb mongoose

我正在使用MongoDB 2.6.12,需要更新深度嵌入的文档。我知道我无法在https://jira.mongodb.org/browse/SERVER-831使用最新的解决方案,因此我需要找到每个文档和子文档的索引。我已经做到了,并且可以使用robomongo更新单个文档(是的,我仍然会使用它),就像这样:

db.getCollection('Ps').update({'dT.name': 'something', pid: 220 }, { '$set': { 'dT.0.ts.0.th': 90}})

但是,当我在节点脚本中运行以下命令时,我在终端中看到了猫鼬查询,但是数据库中没有任何变化:

let main = async function() {
let ps = [];
try {
    ps = await data.app.Ps.find({"dT.ts.th":{"$lte":1}}).exec();
} catch (e) {
    console.log(e);
}

try {
    for (let p of ps) {
        p.dT.forEach(async function(dT, index) {
            dT.ts.forEach(async function(type, i) {
                let newValue = type.th * 100;
                await data.app.db.collection("Ps").update(
                    {pid: p.pid, "dT.name": dT.name},
                    {$set: {["dT." + index +".ts." + i + ".th"]: newValue}}
                ).exec();
            });
        });
    }
} catch (e) {
    console.log(e);
}
};

main()
.then(() => process.exit())
.catch((e) => console.log(e));

这是我的脚本运行时执行的查询示例:

Mongoose: ps.update({ 'dT.name': 'activity', progId: 220 }, { '$set': { 'dT.1.ts.0.th': 90, updatedAt: new Date("Thu, 19 Jul 2018 16:00:50 GMT"), createdAt: new Date("Thu, 19 Jul 2018 16:00:50 GMT") } }, { overwrite: true })

有人知道为什么单个查询可以在robomongo中工作而不在节点脚本中动态地工作吗?

更新

我在上面的代码段中更改了以下代码:

await data.app.db.collection("Ps").update(
    {pid: p.pid, "dT.name": dT.name},
    {$set: {["dT." + index +".ts." + i + ".th"]: newValue}}
).exec();

收件人:

console.log("Before: " + p.dT[index].ts[i].th);
p.dT[index].ts[i].set("th", newValue);
console.log("After: " + p.dT[index].ts[i].th);
p.save(function (error, result) {
   console.log("here");
});

我的控制台消息显示program属性正在更改,但是在终端中没有看到猫鼬查询。我相信这应该适用于http://mongoosejs.com/docs/faq.html上的文档。不是,那是怎么回事?

1 个答案:

答案 0 :(得分:0)

最后,我不得不更改文档update的处理方式。我将查询条件作为第一个参数传递到update()中,这是更新文档应存放的位置。这导致猫鼬将您的更新文档解释为options参数,导致这些路径没有更改。

我还必须使用索引选择器更改构建文档中要更改项目的键的方式,如下所示:

for (let p of ps) {
        let update = { $set: { } };
        p.dT.forEach(async function(dT, index1) {
            dT.types.forEach(async function(type, index2) {
                update.$set[`dT.${index1}.types.${index2}.th`] = type.th * 100;
            });
        });
        await program.update(update);
    }

我希望这对找到该节点解决方案的人有所帮助。我从https://gitter.im/Automattic/mongoose的人那里得到了反馈,所以谢谢他们。