2013-08-07 21 views
5

in meiner Sammlung jedes Dokument hat 2 Termine, modifiziert und synchronisieren. Ich würde gerne diejenigen finden, die> Synchronisation geändert haben, oder die Synchronisation existiert nicht.Vergleichen Sie zwei Datumsfelder in MongoDB

Ich versuchte

{'modified': { $gt : 'sync' }} 

aber es zeigt nicht, was ich erwartet hatte. Irgendwelche Ideen?

Dank

Antwort

17

Sie können ein Feld nicht mit dem Wert eines anderen Felds mit dem normalen Abfrageabgleich vergleichen. Allerdings können Sie dies mit dem Aggregations Rahmen tun:

db.so.aggregate([ 
    { $match: …your normal other query… }, 
    { $match: { $eq: [ '$modified', '$sync' ] } } 
]); 

Ich habe ... Ihre normale andere Abfrage ... da drin, wie Sie das Bit den Index verwenden, machen kann. Also, wenn Sie dies nur für Dokumente tun wollen, wo das name Feld ist charles können Sie tun:

db.so.ensureIndex({ name: 1 }); 
db.so.aggregate([ 
    { $match: { name: 'charles' } }, 
    { $project: { 
     modified: 1, 
     sync: 1, 
     name: 1, 
     eq: { $cond: [ { $gt: [ '$modified', '$sync' ] }, 1, 0 ] } 
    } }, 
    { $match: { eq: 1 } } 
]); 

Mit der Eingabe:

{ "_id" : ObjectId("520276459bf0f0f3a6e4589c"), "modified" : 73845345, "sync" : 73234 } 
{ "_id" : ObjectId("5202764f9bf0f0f3a6e4589d"), "modified" : 4, "sync" : 4 } 
{ "_id" : ObjectId("5202765b9bf0f0f3a6e4589e"), "modified" : 4, "sync" : 4, "name" : "charles" } 
{ "_id" : ObjectId("5202765e9bf0f0f3a6e4589f"), "modified" : 4, "sync" : 45, "name" : "charles" } 
{ "_id" : ObjectId("520276949bf0f0f3a6e458a1"), "modified" : 46, "sync" : 45, "name" : "charles" } 

Das gibt:

{ 
    "result" : [ 
     { 
      "_id" : ObjectId("520276949bf0f0f3a6e458a1"), 
      "modified" : 46, 
      "sync" : 45, 
      "name" : "charles", 
      "eq" : 1 
     } 
    ], 
    "ok" : 1 
} 

Wenn Sie Möchten Sie weitere Felder, müssen Sie sie in der $project hinzufügen.

+0

Danke Jungs, sowohl Aggr und Abfrage sollte funktionieren. –

+1

Sie sollten die '' $ where'' Variante jedoch wirklich meiden, da sie Javascript durchläuft. Bitte akzeptieren Sie die Antwort. – Derick

-1

Gerade jetzt Ihre Abfrage versucht, alle Ergebnisse so zurück, dass das modified Feld als das 'sync' Wort größer ist. Versuchen Sie, die Zitate um sync loszuwerden und sehen Sie, ob das irgendetwas behebt. Ansonsten habe ich ein wenig recherchiert und this question gefunden. Was Sie versuchen, ist in einer einzelnen Abfrage möglicherweise nicht möglich, aber Sie sollten in der Lage sein, Ihre Daten zu manipulieren, sobald Sie alles aus der Datenbank abgerufen haben.

+0

Danke @ gr3co, ich versuchte Aggregation zu vermeiden, aber scheint wie der einzige Weg nach vorne ... :( –

-1

um dieses Problem zu beheben, ohne Aggregation Ihre Anfrage an das ändern: {'modified': { $gt : ISODate(this.sync) }}

1

Einfach

db.collection.find({$where:"this.modified>this.sync"}) 

Beispiel

Kobkrits-MacBook-Pro-2:~ kobkrit$ mongo 
MongoDB shell version: 3.2.3 
connecting to: test 
> db.time.insert({d1:new Date(), d2: new Date(new Date().getTime()+10000)}) 
WriteResult({ "nInserted" : 1 }) 
> db.time.find() 
{ "_id" : ObjectId("577a619493653ac93093883f"), "d1" : ISODate("2016-07-04T13:16:04.167Z"), "d2" : ISODate("2016-07-04T13:16:14.167Z") } 
> db.time.find({$where:"this.d1<this.d2"}) 
{ "_id" : ObjectId("577a619493653ac93093883f"), "d1" : ISODate("2016-07-04T13:16:04.167Z"), "d2" : ISODate("2016-07-04T13:16:14.167Z") } 
> db.time.find({$where:"this.d1>this.d2"}) 
> db.time.find({$where:"this.d1==this.d2"}) 
> 
0

Verwenden Sie Javascript, verwenden foreach und Konvertieren in toDateString Date()

db.ledgers.find({}).forEach(function(item){ 

    if(item.fromdate.toDateString() == item.todate.toDateString()) 
    { 
     printjson(item) 
    } 
})