【问题标题】:Updating deeply embedded documents with MongoDB 2.6.12使用 MongoDB 2.6.12 更新深度嵌入的文档
【发布时间】:2018-07-26 23:05:35
【问题描述】:

我使用的是 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}})

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

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 中有效,而不是在节点脚本中动态?

更新

我在上面的 sn-p 中更改了以下代码:

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");
});

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

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    最后,我不得不改变处理文档update 的方式。我将查询条件作为第一个参数传递给update(),这是更新文档应该去的地方。这导致猫鼬将您的我的更新文档解释为选项参数,导致这些路径没有任何变化。

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

    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 的人的反馈,非常感谢他们。

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多