【问题标题】:mongo db update changing the order of object fieldsmongodb更新更改对象字段的顺序
【发布时间】:2014-04-07 15:36:44
【问题描述】:

我遇到了一个奇怪的问题,不确定我到底错过了什么。

我的收藏中有一个对象列表,如下所示..

{ "_id" : ObjectId("5340eff554f98e32c5990b4f"), "Day" : 8, "Time" : 1553, "State" : "Florida", "Airport" : "ORL", "Temperature" : 82, "Humidity" : 55, "Wind Speed" : 5, "Wind Direction" : 170, "Station Pressure" : 29.97, "Sea Level Pressure" : 196 }
{ "_id" : ObjectId("5340eff554f98e32c5990b5f"), "Day" : 9, "Time" : 1253, "State" : "Florida", "Airport" : "ORL", "Temperature" : 82, "Humidity" : 60, "Wind Speed" : 13, "Wind Direction" : 190, "Station Pressure" : 29.91, "Sea Level Pressure" : 175 }
{ "_id" : ObjectId("5340eff554f98e32c5990b60"), "Day" : 9, "Time" : 1353, "State" : "Florida", "Airport" : "ORL", "Temperature" : 82, "Humidity" : 58, "Wind Speed" : 11, "Wind Direction" : 190, "Station Pressure" : 29.88, "Sea Level Pressure" : 166 }
{ "_id" : ObjectId("5340eff554f98e32c5990b4c"), "Day" : 8, "Time" : 1253, "State" : "Florida", "Airport" : "ORL", "Temperature" : 81, "Humidity" : 54, "Wind Speed" : 4, "Wind Direction" : 180, "Station Pressure" : 30.02, "Sea Level Pressure" : 214 }

从使用 mongo db 驱动程序的节点客户端,我正在执行更新查询,如下所示。基本上它是我试图将“month_high”标志添加到包含该州最高温度的对象的实际代码的一部分。

var updateQuery = {'_id':doc['_id']};
var operator = {$set:{'month_high' : true}};                
db.collection('temps').update(updateQuery,operator,callback)

问题是在更新之后,它更新了正确的对象,但它的字段重新排序如下(注意第一个对象)

{ "Airport" : "ORL", "Day" : 8, "Humidity" : 55, "Sea Level Pressure" : 196, "State" : "Florida", "Station Pressure" : 29.97, "Temperature" : 82, "Time" : 1553, "Wind Direction" : 170, "Wind Speed" : 5, "_id" : ObjectId("5340eff554f98e32c5990b4f"), "month_high" : true }
 { "_id" : ObjectId("5340eff554f98e32c5990b5f"), "Day" : 9, "Time" : 1253, "State" : "Florida", "Airport" : "ORL", "Temperature" : 82, "Humidity" : 60, "Wind Speed" : 13, "Wind Direction" : 190, "Station Pressure" : 29.91, "Sea Level Pressure" : 175 }
 { "_id" : ObjectId("5340eff554f98e32c5990b60"), "Day" : 9, "Time" : 1353, "State" : "Florida", "Airport" : "ORL", "Temperature" : 82, "Humidity" : 58, "Wind Speed" : 11, "Wind Direction" : 190, "Station Pressure" : 29.88, "Sea Level Pressure" : 166 }
 { "_id" : ObjectId("5340eff554f98e32c5990b4c"), "Day" : 8, "Time" : 1253, "State" : "Florida", "Airport" : "ORL", "Temperature" : 81, "Humidity" : 54, "Wind Speed" : 4, "Wind Direction" : 180, "Station Pressure" : 30.02, "Sea Level Pressure" : 214 }

【问题讨论】:

  • 你确定是那个代码做的吗?在我看来,好像其他一些代码已经在结果更新中对所有键进行了排序。您的新字段按预期结束,但我认为其他内容首先修改了此记录。尝试重新制作。
  • 好的,我将我的查询更改如下,但现在更新对象的字段顺序没有搞砸。我们真的必须将整个 doc 对象传递给 update 方法吗? var updateQuery = {}; updateQuery['_id'] = 文档['_id']; doc['month_high'] = true; db.collection('temps').update(updateQuery,doc, callback) {
  • 集合是无序集合。仅当您使用运算符sort () 时,您才能期望文档按某种顺序排列。否则,文档的顺序取决于实现。
  • 这是问题:jira.mongodb.org/browse/SERVER-2592,它已在 2.6 中修复

标签: mongodb


【解决方案1】:

你也可以使用MongoDB projection(推荐方式)

db.collection.find(,);

示例如下:

db.collection.find({},{
   "Airport":1,
   "Day":1,
   "Humidity":1,
   "Sea Level Pressure":1,
   "State":1,
   "Station Pressure":1,
   "Temperature":1,
   "Time":1,
   "Wind Direction":1,
   "Wind Speed":1,
   "_id":1,
   "month_high":1
});

为您提供预期的输出,即

{
   "Airport":"ORL",
   "Day":8,
   "Humidity":55,
   "Sea Level Pressure":196,
   "State":"Florida",
   "Station Pressure":29.97,
   "Temperature":82,
   "Time":1553,
   "Wind Direction":170,
   "Wind Speed":5,
   "_id":ObjectId("5340eff554f98e32c5990b4f"),
   "month_high":true
}, ...


另一种方法是将文档导入 Node.js 后,您可以重新排序 JSON 中的字段。

示例:

var json = {"name": "David", "age" : 78, "NoOfVisits" : 4   };
console.log(json);
//outputs - Object {name: "David", age: 78, NoOfVisits: 4}
//change order to NoOfVisits,age,name

var k = JSON.parse(JSON.stringify( json, ["NoOfVisits","age","name"] , 4));
console.log(k);
//outputs - Object {NoOfVisits: 4, age: 78, name: "David"} 

将所需的键顺序放入数组中并提供给函数。然后将结果解析回 JSON。


发生的原因:

MongoDB 根据特定的填充因子为新文档分配空间。如果您的更新增加了文档的大小,超出了最初分配的大小,则文档将被移动到集合的末尾。同样的概念也适用于文档中的字段。

如果您真的有兴趣并想深入了解,这里是更多链接information

【讨论】:

    【解决方案2】:

    基本上您遇到的问题归结为:https://jira.mongodb.org/browse/SERVER-2592 已在 2.6 中修复。

    从 2.6 开始应保留文档字段顺序。目前,您确实必须做周围的工作。

    【讨论】:

      【解决方案3】:

      我的查询中的以下更改解决了该问题。现在更新后,字段/属性的顺序不会搞砸了。

      这段代码实际上是按状态对对象进行分组,对于每个状态,我按降序对记录进行排序,并将标志“month_high”添加到温度最高的对象。

      db.collection('data').aggregate([{$group:{"_id":"$State"}}],function(err,results){
          for(var i=0;i<results.length;i++){
      
          var query = {'State':results[i]._id};
          var cursor = db.collection('data').find(query);
              cursor.limit(1);
              cursor.sort('Temperature',-1);
      
              cursor.each(function(err, doc) {
                  if(err) throw err;
                  if(doc == null) {
                      return;
                  }
      
       // I just had to change the following query and it worked for me
       // rest of the code remains same.
                        var updateQuery = {};
                     updateQuery['_id'] = doc['_id'];
              doc['month_high'] = true;
      
         db.collection('data').update(updateQuery,doc, function(err, updated) {
                          if(err) throw err;
      
                          console.dir("Successfully updated " + updated + " document!");
      
                          return;
                      });             
                  //console.dir(doc._id);
              });
        }
      });
      

      仍然不确定我的查询是什么时候出现的,为什么它不起作用

      var updateQuery = {'_id':doc['_id']};
      var operator = {$set:{'month_high' : true}};
      db.collection('data').update(updateQuery,operator,callback)
      

      【讨论】:

        猜你喜欢
        • 2014-07-24
        • 2019-07-04
        • 2018-06-09
        • 2019-06-02
        • 1970-01-01
        • 1970-01-01
        • 2017-05-28
        • 1970-01-01
        • 2020-05-20
        相关资源
        最近更新 更多