2013-08-07 20 views
5

nella mia collezione ogni documento ha 2 date, modificato e sincronizzato. Mi piacerebbe trovare quelli che hanno modificato> sincronizzazione, o la sincronizzazione non esiste.Confronta due campi data in MongoDB

ho cercato

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

ma non è mostrare quello che mi aspettavo. Qualche idea?

Grazie

risposta

17

Non è possibile confrontare un campo con il valore di un altro campo con la normale corrispondenza della query. Tuttavia, si può fare questo con il quadro di aggregazione:

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

ho messo ... il vostro normale altra query ... in là come si può fare quel po 'utilizzare l'indice. Quindi, se si vuole fare questo per solo i documenti in cui il campo name è charles si può fare:

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

Con l'ingresso:

{ "_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" } 

Ciò restituisce:

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

Se vuoi altri campi, devi aggiungerli nello $project.

+0

Grazie ragazzi, sia Aggr che query dovrebbero funzionare. –

+1

Dovresti davvero evitare la variante '' $ dove'', dato che passa attraverso Javascript. Inoltre, si prega di accettare la risposta. – Derick

-1

In questo momento la query sta cercando di restituire tutti i risultati in modo tale che il campo modified è maggiore la parola 'sync'. Prova a eliminare le virgolette intorno a sync e verifica se ciò risolve qualsiasi problema. Altrimenti, ho fatto una piccola ricerca e ho trovato this question. Quello che stai cercando di fare potrebbe non essere possibile in una singola query, ma dovresti essere in grado di manipolare i tuoi dati una volta estratto tutto dal database.

+0

Grazie @ gr3co, stavo cercando di evitare l'aggregazione, ma sembra l'unica via da seguire ... :( –

-1

Per risolvere questo problema, senza aggregazione modificare la tua ricerca a questo: {'modified': { $gt : ISODate(this.sync) }}

1

Semplicemente

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

Esempio

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

utilizzare JavaScript, utilizzare foreach e Data convertire in toDateString()

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

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