Jak już wspomniano, trzeba najpierw zmienić schemat tak, że pole created_at
posiada date obiektów w przeciwieństwie do łańcucha jak jest obecna sytuacja, to można wyszukać swoją kolekcję albo stosując metodę find()
lub agregację struktura. To pierwsze byłoby najprostszym podejściem.
Aby przekonwertować created_at
najświeższe dziedzinie, trzeba by iteracji kursor zwrócony przez metodę find()
stosując metodę forEach()
, wewnątrz pętli konwertować pole created_at
do obiektu Date, a następnie zaktualizować pole za pomocą Operator $set
.
Weź Zaletą korzystania z Bulk API dla zbiorczych aktualizacji, które oferują lepszą wydajność, jak będziesz wysyłania operacji do serwera w partii mówią 1000, która daje lepszą wydajność, jak nie podając wszelkie żądania do serwera , tylko raz na każde 1000 próśb.
Poniższe ilustruje to podejście, w pierwszym przykładzie użyto interfejsu API zbiorczego dostępnego w wersjach MongoDB >= 2.6 and < 3.2
. Aktualizuje wszystkie dokumenty w kolekcji, zmieniając created_at
pola do pola Data:
var bulk = db.collection.initializeUnorderedBulkOp(),
counter = 0;
db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
var newDate = new Date(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(); }
Następny przykład dotyczy nowego MongoDB wersji 3.2
który ma od deprecated the Bulk API i dostarczonych nowszą zbiór API, za pomocą bulkWrite()
:
var cursor = db.collection.find({"created_at": {"$exists": true, "$type": 2 }}),
bulkOps = [];
cursor.forEach(function (doc) {
var newDate = new Date(doc.created_at);
bulkOps.push(
{
"updateOne": {
"filter": { "_id": doc._id } ,
"update": { "$set": { "created_at": newDate } }
}
}
);
if (bulkOps.length === 1000) {
db.collection.bulkWrite(bulkUpdateOps);
bulkOps = [];
}
});
if (bulkOps.length > 0) { db.collection.bulkWrite(bulkOps); }
po modyfikacji schematu jest pełna, można następnie kwerendy swoją kolekcję na dzień:
var dt = new Date("2016/01/01");
db.collection.find({ "created_at": { "$gt": dt } });
A jeśli chcesz zapytać przy użyciu frameworka agregacji, uruchom następujący potok, aby uzyskać pożądany wynik.Używa $match
operatora, który jest podobny do sposobu find()
:
var dt = new Date("2016/01/01");
db.collection.aggregate([
{
"$match": { "created_at": { "$gt": dt } }
}
])
nie ma sposobu, aby przekonwertować ciąg na bieżąco w rurociągu agregacji, natomiast data ciąg może być. Możesz oszukać: utwórz kopię swojej kolekcji i przechowuj 'created_at' jako ISODate, a następnie porównuj daty ... – Valijon
Nie musisz niczego konwertować dla swojego zapytania; '{created_at: {$ gt: '2016/01/01'}}' działałoby dobrze, ponieważ twój format ciągu obsługuje sensowne porównanie. – JohnnyHK
@JohnnyHK: to działa tak dobrze, nie rozpoznaję tego. Dziękuję bardzo – user1697646