Как преобразовать свойство в MongoDB из текста в дату?

В MongoDB у меня есть документ с полем "ClockInTime", который был импортирован из CSV в виде строки.

Как выглядит соответствующий оператор db.ClockTime.update(), чтобы преобразовать эти текстовые значения в тип данных даты?

Ответ 1

Этот код должен сделать это:

> var cursor = db.ClockTime.find()
> while (cursor.hasNext()) {
... var doc = cursor.next();
... db.ClockTime.update({_id : doc._id}, {$set : {ClockInTime : new Date(doc.ClockInTime)}})
... }

Ответ 2

У меня точно такая же ситуация, как у Джеффа Фрица.

В моем случае я преуспею в следующем упрощенном решении:

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

Ответ 3

Это общий пример кода в python с использованием pymongo

from pymongo import MongoClient
from datetime import datetime

def fixTime(host, port, database, collection, attr, date_format):
    #host is where the mongodb is hosted eg: "localhost"
    #port is the mongodb port eg: 27017
    #database is the name of database eg : "test"
    #collection is the name of collection eg : "test_collection"
    #attr is the column name which needs to be modified
    #date_format is the format of the string eg : "%Y-%m-%d %H:%M:%S.%f"
    #http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
    client = MongoClient(host, port)
    db = client[database]
    col = db[collection]
    for obj in col.find():
        if obj[attr]:
            if type(obj[attr]) is not datetime:
                time = datetime.strptime(obj[attr],date_format)
                col.update({'_id':obj['_id']},{'$set':{attr : time}})

для получения дополнительной информации: http://salilpa.com/home/content/how-convert-property-mongodb-text-date-type-using-pymongo

Ответ 4

Если вам нужно проверить, было ли поле уже преобразовано, вы можете использовать это условие:

/usr/bin/mongo mydb --eval 'db.mycollection.find().forEach(function(doc){
    if (doc.date instanceof Date !== true) {
        doc.date = new ISODate(doc.date);
        db.mycollection.save(doc);
    }
});'

В противном случае командная строка может сломаться.

Ответ 5

Запуск Mongo 4.x:

  • db.collection.update() может принять конвейер агрегации, что в конечном итоге позволяет обновить поле на основе его текущего значения (Mongo 4.2+).
  • Появился новый оператор агрегации $toDate (Mongo 4.0).

Такой что:

// { a: "2018-03-03" }
db.collection.update(
  {},
  [{ $set: { a: { $toDate: "$a" } } }],
  { multi: true }
)
// { a: ISODate("2018-03-03T00:00:00Z") }
  • Первая часть {} - это запрос на совпадение, который фильтрует, какие документы обновлять (в данном случае все документы).

  • Вторая часть [{ $set: { a: { $toDate: "$a" } } }] представляет собой конвейер агрегации обновлений (обратите внимание на квадратные скобки, обозначающие использование конвейера агрегации). $set - новый оператор агрегирования, который в этом случае заменяет значение поля. ISODate значением является само поле, согласованное с объектом ISODate. Обратите внимание, как a изменяется напрямую на основе его собственного значения ($a).

  • Не забудьте { multi: true }, иначе будет обновлен только первый соответствующий документ.