2014-01-10 62 views
0

我使用Node.js和MongoDB与猫鼬。 当我执行下面的代码时,第一个更新代码工作正常。但是在插入'bar'的第二个更新查询中出现错误'not okForStorage'。不okForForStorage MongoDB中的错误,Node.Js(猫鼬)

它的循环和插入数据一遍又一遍,但错误发生在第一次插入,所以我不认为这是有效载荷问题,也没有任何其他硬件问题。

analyze('SomeText',function(err,data){ 
if(err) throw err; 
    for(var i=0; i < data.foo.length;i++){ 
     if(!data.foo[i]){ 
      continue; 
     } 
     var condtion = { foo: data.foo[i]}; 
     var update = { 
      $inc :{totalcounter : 1}, 
      counter : { 
       date : dateformat(new Date(), "yyyymmdd"), 
       $inc :{counter : 1} 
      } 
     }; 
     db.foodb.update(condtion,update,{upsert : true},function(err, numberAffected, raw){ 
      if(err) throw err; 
      //Data added successfully 
     }); 
     for(var g=0;g < data.bar[i].length;g++){ 
      update = { 
       bar : { 
        foo : data.bar[i][g], 
        $inc : { totalcounter : 1}, 
        counter : { 
         date : dateformat(new Date(), "yyyymmdd"), 
         $inc :{counter : 1} 
        } 
       } 
      }; 
      db.foodb.update(condtion,update,{upsert : true},function(err, numberAffected, raw){ 
       if(err) throw err; 
       //getting error here 'MongoError: not okForStorage' 
      }); 
     } 
    } 
}); 

假设保留的数据是一样的东西

data.foo = ['10','20','30']; 
data.bar = [[11,12,13],[21,22,23],[31,32,33]]; 

,我多么想将数据插入到数据库是

{ 
    foo : 10, 
    totalcounter : 1, 
    counter :{ date : 20131231,counter : 1}, 
    bar : {[ foo : 11,totalcounter : 1,counter : {date : 20131231,counter : 1}], 
    [foo : 12,totalcounter : 1,counter : {date : 20131231,counter : 1}], 
    [foo : 13,totalcounter : 1,counter : {date : 20131231,counter : 1}] 
    } 
} 

此外,即使我明确地分配时间如'20131231'。它将被忽略,ISODate类型(1970-01-01T05:35:40.109Z)中的默认时间将被保存。 据我所知,我需要遵循IOSDate格式类型来存储日期。 但我不想因为某些原因包含小时和分钟/秒。 除了将'date'设置为Number对象之外,是否有任何有效的方法来做到这一点?

谢谢你的一切协助。

+0

我到目前为止发现的是使用'$ inc'的方式是错误的。 看来我需要把它们放在一起但是“$ inc:{totalcounter:1,counter.counter:1}”给我一个语法错误。这可能是一个非常新手的问题,但任何人都可以提出正确的写法吗? – suish

回答

1

更新的第一个代码正常工作。但是在插入'bar'的第二个更新查询中出现错误'not okForStorage'。

根据您粘贴的代码,我不确定第一次更新如何成功执行。在这两种情况下,您都在同一更新对象中混合更新运算符和字段替换(update()的第二个参数)。这在db.collection.update() documentation中讨论过,它也适用于驱动程序。

在你的第一次更新,你的意思是设置counter.date领域,并增加其他两个字段,所以您的更新对象应该是:

{ 
    $inc: { totalcounter : 1, "counter.counter": 1 }, 
    $set: { date : dateformat(new Date(), "yyyymmdd") } 
} 

关于你的示例文档,你写道:

我想如何将数据插入到数据库中:

{ 
    foo : 10, 
    totalcounter : 1, 
    counter :{ date : 20131231,counter : 1}, 
    bar : {[ foo : 11,totalcounter : 1,counter : {date : 20131231,counter : 1}], 
    [foo : 12,totalcounter : 1,counter : {date : 20131231,counter : 1}], 
    [foo : 13,totalcounter : 1,counter : {date : 20131231,counter : 1}] 
    } 
} 

我认为您的示例值bar中存在一些错字。应该是一个对象数组?如果是这样,你应该使用array update operators之一,如$push,如果你的意思是追加一个新的对象到数组。如果您的意思是使用常规修饰符(例如$inc,$set)来更新现有的阵列元素,则可以参考要使用点语法进行更新的字段,例如阵列中第一个对象内的counter字段的bar.0.counter

此外,即使我明确指定时间,如'20131231'。它将被忽略,ISODate中的默认时间(“1970-01-01T05:35:40.109Z”)将被保存。我明白,我需要遵循IOSDate格式类型来存储日期。但我不想因为某些原因而包含小时和分钟/秒。除了将'date'设置为Number对象之外,是否有任何有效的方法来做到这一点?

我假设你的猫鼬架构映射date场和字符串'20131231'不是有效的构造函数的参数和空ISODate正在创建结果。 BSON日期类型存储自纪元以来的毫秒数,为64位整数。如果您想忽略小时和更小的时间量度,则可以简单地为所有这些度量创建一个零时间戳。

如果您坚持为date字段存储“YYYYMMDD”字符串,您只需更改Mongoose中的映射,以便该字段是基本字符串。