wake-up-neo.net

Umwandlung von String in Mongodb in Datum

Gibt es eine Möglichkeit, Zeichenfolge mithilfe eines benutzerdefinierten Formats mithilfe der Mongodb-Shell in ein Datum zu konvertieren

Ich versuche, "21/Mai/2012: 16: 35: 33 -0400" bis heute zu konvertieren.

Gibt es eine Möglichkeit, DateFormatter oder etwas an die Date.parse(...)- oder ISODate(....)-Methode zu übergeben?

22
user883257

Sie können das Javascript in dem zweiten Link verwenden, der von Ravi Khakhkhar bereitgestellt wird, oder Sie müssen einige Zeichenfolgenmanipulationen durchführen, um Ihre Originalzeichenfolge zu konvertieren (da einige der Sonderzeichen in Ihrem ursprünglichen Format nicht als gültige Begrenzungszeichen erkannt werden), sondern Sobald Sie das getan haben, können Sie "neu" verwenden. 

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")

Hier sind einige Links, die für Sie nützlich sein könnten (hinsichtlich der Änderung der Daten in der Mongo-Shell): 

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

7
Mark Hillick

In meinem Fall gelingt es mir mit der folgenden Lösung, das Feld ClockInTime aus der ClockTime-Collection von String in Date-Typ umzuwandeln:

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

Verwenden von MongoDB 4.0 und neuer

Der Operator $toDate konvertiert den Wert in ein Datum. Wenn der Wert nicht in ein Datum konvertiert werden kann, werden $toDate fehlerhaft. Wenn der Wert Null ist oder fehlt, gibt $toDate Null zurück:

Sie können es wie folgt in einer aggregierten Pipeline verwenden:

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

Das oben Genannte entspricht der Verwendung des $convert Operators wie folgt:

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

Verwenden von MongoDB 3.6 und neuer

Sie können auch den Operator $dateFromString verwenden, der die Datums-/Zeitzeichenfolge in ein Datumsobjekt konvertiert und über Optionen zur Angabe des Datumsformats sowie der Zeitzone verfügt:

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

MongoDB-Versionen verwenden >= 2.6 and < 3.2

Wenn die MongoDB-Version nicht über die systemeigenen Operatoren verfügt, die die Konvertierung durchführen, müssen Sie den von der Methode find() zurückgegebenen Cursor manuell iterieren, indem Sie die Methode forEach() verwenden oder die Cursormethode next(), um auf die Dokumente zuzugreifen. Konvertieren Sie das Feld in der Schleife in ein ISODate-Objekt und aktualisieren Sie das Feld anschließend mit dem Operator -_$set, wie im folgenden Beispiel, in dem das Feld created_at heißt und das Datum aktuell im Zeichenfolgenformat enthält:

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)}}
    ) 
};

Um die Leistung insbesondere bei großen Sammlungen zu verbessern, nutzen Sie die Bulk API für Massenaktualisierungen, da Sie die Vorgänge in Batches von beispielsweise 1000 an den Server senden Sie senden nicht jede Anfrage an den Server, sondern nur alle 1000 Anfragen. 

Im Folgenden wird dieser Ansatz veranschaulicht. Das erste Beispiel verwendet die Bulk-API, die in den MongoDB-Versionen >= 2.6 and < 3.2 verfügbar ist. Es aktualisiert alle Dokumente in der Sammlung, indem die created_at-Felder in Datumsfelder geändert werden:

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(); }

MongoDB 3.2 verwenden

Das nächste Beispiel bezieht sich auf die neue MongoDB-Version 3.2, die seit die Bulk-API nicht mehr unterstützt und einen neueren Satz von apis mit - bulkWrite() bereitgestellt hat:

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);
13
chridam

Ich hatte im MongoDB Stored einige Zeichenfolgen, die in ein ordnungsgemäßes und gültiges dateTime-Feld in der Mongodb umgewandelt werden mussten.

hier ist mein Code für das spezielle Datumsformat: "2014-03-12T09: 14: 19.5303017 + 01: 00"

aber Sie können diese Idee leicht annehmen und Ihre eigene Regex schreiben, um die Datumsformate zu analysieren:

// 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");
    }
})
3
Pascalsz

Sie können die Aggregation $dateFromString verwenden, die das String-Datum in das ISO-Datum konvertiert

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

Wie wäre es mit einer Bibliothek wie momentjs , indem Sie ein Skript wie folgt schreiben:

[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,
    });

Laden Sie dann das Skript wie folgt in die Befehlszeile: 

> mongo install_moment.js

Verwenden Sie es in Ihrer nächsten Mongo-Sitzung schließlich so: 

// 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"
0
Jthorpe