Преобразование строки в дату в mongodb

Есть ли способ конвертировать строку в дату, используя пользовательский формат, используя оболочку mongodb

Я пытаюсь преобразовать & quot; 21 мая / 2012: 16: 35: 33 -0400 & quot; на свидание,

Есть ли способ пройтиDateFormatter или что-то Date.parse(...) или жеISODate(....) метод?

Ответы на вопрос(6)

Using MongoDB 4.0 and newer

$toDate Оператор преобразует значение в дату. Если значение не может быть преобразовано в дату,$toDate ошибки. Если значение равно нулю или отсутствует,$toDate возвращает ноль:

Вы можете использовать его в агрегированном конвейере следующим образом:

db.collection.aggregate([
    { "$addFields": {
        "created_at": {
            "$toDate": "$created_at"
        }
    } }
])

Вышеуказанное эквивалентно использованию$convert Оператор следующим образом:

db.collection.aggregate([
    { "$addFields": {
        "created_at": { 
            "$convert": { 
                "input": "$created_at", 
                "to": "date" 
            } 
        }
    } }
])

Using MongoDB 3.6 and newer

Вы также можете использовать$dateFromString Оператор, который преобразует строку даты / времени в объект даты и имеет опции для указания формата даты, а также часового пояса:

db.collection.aggregate([
    { "$addFields": {
        "created_at": { 
            "$dateFromString": { 
                "dateString": "$created_at",
                "format": "%m-%d-%Y" /* <-- option available only in version 4.0. and newer */
            } 
        }
    } }
])

Using MongoDB versions >= 2.6 and < 3.2

Если версия MongoDB не имеет собственных операторов, которые выполняют преобразование, вам нужно будет вручную перебрать курсор, возвращаемыйfind() метод с помощьюforEach() метод или метод курсораnext() для доступа к документам. С помощью цикла конвертируйте поле в объект ISODate, а затем обновите поле, используя$set оператор, как в следующем примере, где поле называетсяcreated_at и в настоящее время содержит дату в строковом формате:

var cursor = db.collection.find({"created_at": {"$exists": true, "$type": 2 }}); 
while (cursor.hasNext()) { 
    var doc = cursor.next(); 
    db.collection.update(
        {"_id" : doc._id}, 
        {"$set" : {"created_at" : new ISODate(doc.created_at)}}
    ) 
};

Для повышения производительности, особенно при работе с большими коллекциями, используйтеМассовое API для массовых обновлений, поскольку вы будете отправлять операции на сервер партиями, скажем, 1000, что дает вам лучшую производительность, поскольку вы не отправляете каждый запрос на сервер, только один раз на каждые 1000 запросов.

Следующее демонстрирует этот подход, первый пример использует Bulk API, доступный в версиях MongoDB>= 2.6 and < 3.2, Обновляет все документы в коллекции путем измененияcreated_at поля на дату поля:

var bulk = db.collection.initializeUnorderedBulkOp(),
    counter = 0;

db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
    var newDate = new ISODate(doc.created_at);
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "created_at": newDate}
    });

    counter++;
    if (counter % 1000 == 0) {
        bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})
// Clean up remaining operations in queue
if (counter % 1000 != 0) { bulk.execute(); }

Using MongoDB 3.2

Следующий пример относится к новой версии MongoDB3.2 который с тех порустарел Bulk API и предоставил новый набор API, используяbulkWrite():

var bulkOps = [],
    cursor = db.collection.find({"created_at": {"$exists": true, "$type": 2 }});

cursor.forEach(function (doc) { 
    var newDate = new ISODate(doc.created_at);
    bulkOps.push(         
        { 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "created_at": newDate } } 
            }         
        }           
    );

    if (bulkOps.length === 500) {
        db.collection.bulkWrite(bulkOps);
        bulkOps = [];
    }     
});

if (bulkOps.length > 0) db.collection.bulkWrite(bulkOps);

Ты можешь использовать$dateFromString агрегация, которая преобразует строковую дату в дату ISO

db.collection.aggregate([
  {
    "$project": {
      "date": {
        "$dateFromString": {
          "dateString": "$date"
        }
      }
    }
  }
])

Как насчет использования библиотеки, какmomentjs написав такой скрипт:

[install_moment.js]
function get_moment(){
    // shim to get UMD module to load as CommonJS
    var module = {exports:{}};

    /* 
    copy your favorite UMD module (i.e. moment.js) here
    */

    return module.exports
}
//load the module generator into the stored procedures: 
db.system.js.save( {
        _id:"get_moment",
        value: get_moment,
    });

Затем загрузите скрипт в командной строке следующим образом:

> mongo install_moment.js

Наконец, в следующем сеансе монго используйте его так:

// LOAD STORED PROCEDURES
db.loadServerScripts();

// GET THE MOMENT MODULE
var moment = get_moment();

// parse a date-time string
var a = moment("23 Feb 1997 at 3:23 pm","DD MMM YYYY [at] hh:mm a");

// reformat the string as you wish:
a.format("[The] DDD['th day of] YYYY"): //"The 54'th day of 1997"
Решение Вопроса

Вы можете использовать javascript во второй ссылке, предоставленной Рави Хаххаром, или вам придется выполнить некоторые манипуляции со строками, чтобы преобразовать вашу оригинальную строку (поскольку некоторые специальные символы в исходном формате не распознаются как допустимые разделители), но как только вы это сделаете, вы можете использовать & quot; new & quot;

training:PRIMARY> Date()
Fri Jun 08 2012 13:53:03 GMT+0100 (IST)
training:PRIMARY> new Date()
ISODate("2012-06-08T12:53:06.831Z")

training:PRIMARY> var start = new Date("21/May/2012:16:35:33 -0400")        => doesn't work
training:PRIMARY> start
ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ")

training:PRIMARY> var start = new Date("21 May 2012:16:35:33 -0400")        => doesn't work    
training:PRIMARY> start
ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ")

training:PRIMARY> var start = new Date("21 May 2012 16:35:33 -0400")        => works
training:PRIMARY> start
ISODate("2012-05-21T20:35:33Z")

Вот некоторые ссылки, которые вы можете найти полезными (относительно изменения данных в оболочке mongo) -

http://cookbook.mongodb.org/patterns/date_range/

http://www.mongodb.org/display/DOCS/Dates

http://www.mongodb.org/display/DOCS/Overview+-+The+MongoDB+Interactive+Shell

У меня было несколько строк в MongoDB, которые нужно было переформатировать в правильное и действительное поле dateTime в mongodb.

Вот мой код для специального формата даты: & quot; 2014-03-12T09: 14: 19.5303017 + 01: 00 & quot;

но вы можете легко принять эту идею и написать собственное регулярное выражение для разбора форматов даты:

// format: "2014-03-12T09:14:19.5303017+01:00"
var myregexp = /(....)-(..)-(..)T(..):(..):(..)\.(.+)([\+-])(..)/;

db.Product.find().forEach(function(doc) { 
   var matches = myregexp.exec(doc.metadata.insertTime);

   if myregexp.test(doc.metadata.insertTime)) {
       var offset = matches[9] * (matches[8] == "+" ? 1 : -1);
       var hours = matches[4]-(-offset)+1
       var date = new Date(matches[1], matches[2]-1, matches[3],hours, matches[5], matches[6], matches[7] / 10000.0)
       db.Product.update({_id : doc._id}, {$set : {"metadata.insertTime" : date}})
       print("succsessfully updated");
    } else {
        print("not updated");
    }
})

В моем случае мне удалось следующее решение для преобразования поля ClockInTime из коллекции ClockTimefrom string to Date type:

db.ClockTime.find().forEach(function(doc) { 
    doc.ClockInTime=new Date(doc.ClockInTime);
    db.ClockTime.save(doc); 
    })

Ваш ответ на вопрос