Mongodb点域更新 [英] Mongodb dot field update

查看:133
本文介绍了Mongodb点域更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Mongo中有以下架构:

I have the following Schema in Mongo:

var OrderSchema = new Schema({
    postcode: String,
    ...
    status: {
        last_check: { type: Date },
        date: Date,
        code: String,
        postnum: String,
        text: String,
        class: String
    },
});

我有一个保存数据的功能(旧方法已注释):

I have a function to save a data (old way is commented):

function save_order(data) {
//    var order = new Order(data);
//    var upsertData = order.toObject();
//    delete upsertData._id;
//    Order.findOneAndUpdate({postcode: order.postcode}, upsertData, {upsert: true}, function (err) {
  Order.update({postcode: data.postcode}, {$set:data}, function (err) {
    if (err) console.log('err');
  });
}

这里传递给函数的数据示例:

Here data example passed to a function:

{ postcode: 'BV123456789BY',
  status: 
   { last_check: 1413539153572,
     code: '06',
     postnum: '247431',
     date: Thu Oct 16 2014 09:52:00 GMT+0300 (Восточная Европа (лето)),
     text: '06. Поступило в участок обработки почты (247431) Светлогорск - 1' } }

设置status.class的功能正常 - 它不会覆盖状态:

Function to set status.class works fine - it does not overwrite status :

function setByOrderId(id, data) {
//   data = {'status.class': 'danger'}
    Order.update({_id: id}, {$set: data}, function (err) {
        if (err) console.log('err');
    });
}

问题是,当我更新状态时,status.class的值消失...
如何在不覆盖status.code的情况下更新状态?谢谢。

Problem is that when I update the status, the value of status.class disappears... How should I update the status without overwriting status.code? Thank you.

推荐答案

当然它确实如此,因为这正是你要求它做的。尽管你的头衔,但没有使用点符号在这里。如果您不打算覆盖现有属性,这当然是您想要做的。现在你只是替换整个对象,尽管你使用了 $ set 除非您在此处更改结构,否则基本上是多余的。

Of course it does since this is exactly what you are asking it to do. Despite your title, there is no use of "dot notation" here at all. This is of course what you want to do if you intend to not overwrite existing properties. Right now you are just replacing the entire object, despite your use of $set where unless you change the structure here is basically redundant.

To修复这个,你需要先操作你的数据对象。根据以下内容:

To "fix" this, you need to manipulate your data object first. With something along these lines:

var newobj = {};
Object.keys( data ).forEach(function(key) {
    if ( typeof(data[key]) == "object" ) {
       Object.keys( data[key] ).forEach(function(subkey) {
           newobj[key + "." + subkey] = data[key][subkey];
       });
    } else {
       newobj[key] = data[key];
    }
});

这将为您提供 newobj 中的输出结构如下:

That gives you and output in the newobj structure like this:

{
    "postcode" : "BV123456789BY",
    "status.last_check" : 1413539153572,
    "status.code" : "06",
    "status.postnum" : "247431",
    "status.date" : ISODate("2014-10-17T11:28:20.540Z"),
    "status.text" : "06. Поступило в участок обработки почты (247431) Светлогорск - 1"
}

当然,您可以继续进行正常更新并确保一切正常:

Then of course you can proceed with your normal update and get everything right:

Order.update({ "postcode": newobj.postcode}, { "$set": newobj }, function (err) {
    if (err) console.log(err);
});

当然,对于更嵌套的结构,你需要一些递归,但这应该给你一般的想法。点符号是要走的路,但你需要实际使用它。

Of course you would need some recursion for a more nested structure, but this should give you the general idea. Dot notation is the way to go, but you need to actually use it.

这篇关于Mongodb点域更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆