2016-01-17 9 views
5

W kolekcji, przechowywać tego rodzaju dokumentuJak przekonwertować ciąg na bieżąco z agregacją mongo?

{ 
    "_id" : 1, 
    "created_at" : "2016/01/01 12:10:10", 
    ... 
}. 
{ 
    "_id" : 2, 
    "created_at" : "2016/01/04 12:10:10", 
    ... 
} 

chciałbym znaleźć dokumenty mają „creared_at”> 2016/01/01 za pomocą rurociągu agregacji.

Ktoś ma rozwiązanie, aby przekonwertować "created_at" do tej pory, więc można konotować w agregacji?

+0

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

+3

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

+0

@JohnnyHK: to działa tak dobrze, nie rozpoznaję tego. Dziękuję bardzo – user1697646

Odpowiedz

5

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 } } 
    } 
]) 
1

Jeśli mamy do dokumentów:

db.doc.save({ "_id" : 1, "created_at" : "2016/01/01 12:10:10" }) 
db.doc.save({ "_id" : 2, "created_at" : "2016/01/04 12:10:10" }) 

Proste zapytanie:

db.doc.find({ "created_at" : {"$lte": Date()} }) 

Kruszywo zapytania:

db.doc.aggregate([{ 
    "$match": { "created_at": { "$lte": Date() } } 
}]) 
  • Date() metoda, która zwraca bieżącą datę jako ciąg.
  • nowy konstruktor Date(), który zwraca obiekt Date przy użyciu opakowania ISODate().
  • Konstruktor ISODate(), który zwraca obiekt Date za pomocą opakowania ISODate() .

Więcej informacji o rodzaju i daty herehere