2017-06-21 44 views
0

我有我的MongoDB集合看起来像文件:更新文件,通过使用JavaScript函数

{ 
    "gran": "Day", 
    "dix": NumberInt(80), 
    "y": NumberInt(2017), 
}, 
{ 
    "gran": "Month", 
    "dix": NumberInt(3), 
    "y": NumberInt(2017), 
} 

我要添加到这些文档的/场,因此他们希望像:

{ 
    "gran": "Day", 
    "dix": NumberInt(80), 
    "y": NumberInt(2017), 
    "from": ISODate("2017-03-21T00:00:00.000+0000"), 
    "to": ISODate("2017-03-21T23:59:59.000+0000") 
}, 
{ 
    "gran": "Month", 
    "dix": NumberInt(3), 
    "y": NumberInt(2017), 
    "from": ISODate("2017-03-01T00:00:00.000+0000"), 
    "to": ISODate("2017-03-31T23:59:59.000+0000") 
} 

我写了一个JavaScript函数,它把来自粒度到日期:

function(year, index, gran) { 
    var fromToDates = {}; 
    if (gran === "Day") { 
     var initDate = new Date(year, 0); // initialize a date in `year-01-01` 
     var currentDate = new Date(initDate.setDate(index)); // add the number of days 
     var dateFrom = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate(), 0, 0, 0); 
     var dateTo = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate(), 23, 59, 59); 
     fromToDates.from = dateFrom; 
     fromToDates.to = dateTo; 
     return fromToDates; 
    } else if (gran === "Week") { 
     var simple = new Date(year, 0, 1 + (index - 1) * 7); 
     var dow = simple.getDay(); 
     print(dow); 
     var dateFrom = simple; 
     if (dow <= 4) 
      dateFrom.setDate(simple.getDate() - simple.getDay() + 1); 
     else 
      dateFrom.setDate(simple.getDate() + 8 - simple.getDay()); 
     var dateTo = new Date(dateFrom); 

     dateTo.setDate(dateTo.getDate() + 6); 
     dateTo.setUTCHours(23); 
     dateTo.setUTCMinutes(59); 
     dateTo.setUTCSeconds(59); 
     fromToDates.from = dateFrom; 
     fromToDates.to = dateTo; 
     return fromToDates; 

    } else if (gran === "Month") { 
     var monthIndex = index - 1; 
     var initDate = new Date(year, monthIndex); 
     var dateFrom = new Date(initDate.getFullYear(), monthIndex, 1, 0, 0, 0); 
     var lastDayOfMonth = monthIndex + 1; 
     var dateTo = new Date(dateFrom.getFullYear(), lastDayOfMonth, 0, 23, 59, 59); 
     fromToDates.from = dateFrom; 
     fromToDates.to = dateTom; 
     return fromToDates; 
    } else if (gran === "Quarter") { 
     var dateFrom = new Date(year,index*3-3,1); 
     var dateTo = new Date(year,index*3,0, 23, 59, 59); 
     fromToDates.from = dateFrom; 
     fromToDates.to = dateTo; 
     return fromToDates; 
    } 
    else if (gran === "Year") { 
     var dateFrom = new Date(year, 0, 1, 0,0,0); 
     var dateTo = new Date(year, 11, 31, 23, 59, 59); 
     fromToDates.from = dateFrom; 
     fromToDates.to = dateTo; 
     return fromToDates; 
    } 
} 

对于来自/加入这两个领域我想我可以用这个方法:

db.reports.findAndModify({ 
    query: { "from": {$exists: false}}, 
    update: { 
     $set: { 
      "from": new Date(), 
      "to": new Date() 
     } 
    }, 
    multi: true 
}) 

然后我读身边,我可以这样做:

db.reports.aggregate([ 
{ 
    $match: 
    { 
    } 
} 
]).map(function(doc) { 
    var dates = dateIndexToDateWithFromTo(doc.y, doc.dix, doc.gran); 
    doc['from'] = dates.from; 
    doc['to'] = dates.to; 
    return doc; 
}) 

但这是不是真的工作。它会返回正确的日期,但当然不会在集合中更新它们。任何人都知道如何使用我写的脚本动态更新我的文档?

我使用的是mongodb版本3.2,因此对于每个人都会建议在汇总管道中使用$ addFields,这是不可能的,因为我现在无法更新到3.4。

回答

0

我想我找到了它,或者至少它适用于我测试的少量数据。

db.media_code_reports.aggregate([ 
{ 
    $match: 
    { 
    } 
} 
]).map(function(doc) { 
    var dates = dateIndexToDateWithFromTo(doc.y, doc.dix, doc.gran); 
    doc.from = dates.from; 
    doc.to = dates.to; 
    db.media_code_reports.save(doc); 
}) 

我不确定这是否有效。我必须做的,以将字段添加两个步骤:

  1. 先用findAndModify(...)函数
  2. 添加它们,然后使用聚合与空匹配得到的所有文件,然后ajavascript map()函数遍历每个文档。并在地图()内。做一个保存()每个文件。

如果有人有更好的建议请说出来,否则我会认为这是回答。