2012-02-11 1 views
11

Sto cercando di "confrontare" tutti i documenti tra 2 collezioni, che restituiranno solo true e se solo tutti i documenti all'interno di 2 raccolte sono esattamente uguali.Come confrontare 2 collezioni di mongodb?

Ho cercato i metodi sulla raccolta, ma non sono riuscito a trovarne uno in grado di farlo.

ho sperimentato qualcosa di simile a questi nella shell mongo, ma non funziona come mi aspettavo:

db.test1 == db.test2 

o

db.test1.to_json() == db.test2.to_json() 

Comunque, im utilizzando anche MongoDB primavera-dati in Java.

Si prega di condividere i tuoi pensieri! Grazie.

+3

L'uso di 'db.runCommand ('dbHash')' consente di ottenere gli hash per il db e le raccolte, di cui è possibile confrontare un hash di raccolta con un altro hash di raccolta. Potrebbe essere più facile sapere se entrambe le collezioni sono uguali. – Rexford

risposta

13

È possibile provare a utilizzare mongodb eval in combinazione con la funzione di uguale personalizzata, ad esempio this.

I tuoi metodi non funzionano perché nel primo caso si stanno confrontando riferimenti oggetto, che non sono gli stessi. Nel secondo caso, non vi è alcuna garanzia che to_json generi la stessa stringa anche per gli oggetti uguali.

Invece, provare qualcosa di simile:

var compareCollections = function(){ 
    db.test1.find().forEach(function(obj1){ 
     db.test2.find({/*if you know some properties, you can put them here...if don't, leave this empty*/}).forEach(function(obj2){ 
      var equals = function(o1, o2){ 
       // here goes some compare code...modified from the SO link you have in the answer. 
      }; 

      if(equals(ob1, obj2)){ 
       // Do what you want to do 
      } 
     }); 
    }); 
}; 

db.eval(compareCollections); 

Con db.eval si assicura che il codice verrà eseguito sul lato server di database, senza caricare le collezioni per il cliente.

+0

Grazie per l'idea. Se ho capito bene, questo in realtà ha 2 loop, dove 1 documento in test1 sarà testato con tutti i documenti in test2 ..? O forse quello che volevi dire è che nell'argomento test2.find abbiamo inserito l'id di obj1, perché nel mio caso, ciò che è in test1 deve essere nel test2 con lo stesso id. Inoltre, sono abbastanza confuso su cosa succederebbe se test2 avesse più documenti di test1, o se test1 avesse più documenti di test2, il che nel mio caso significherebbe che test1 e test2 non sono uguali. Qualche idea su come rilevarli senza fare il ciclo su entrambi i lati delle collezioni? Grazie ! – bertie

+0

Questo codice passa attraverso entrambe le raccolte e fa qualcosa quando trova una corrispondenza dalla prima raccolta nella seconda raccolta (o puoi fare qualcosa quando la corrispondenza non viene trovata, basta mettere se (! Equals (...) Se vuoi solo per confrontare se entrambe le collezioni sono uguali, questo può essere ottimizzato molto ... per esempio, prima di fare db.test1.find puoi confrontare i conteggi di entrambe le collezioni, come db.test1.find(). count() == db .test2.find(). count() ... e se il conteggio non è uguale, non vi è alcun motivo per continuare. Inoltre, come ho indicato nel codice, se c'è qualche proprietà che conosci (come _id) tu (continua ...) –

+0

può metterlo dentro db.test2.find ({... qui ...}) e velocizzare la ricerca per il secondo oggetto). Quindi, se i tuoi conteggi sono uguali, e non vai mai in (se ! equals (...)) allora le tue collezioni sono uguali ... L'importante è che, alla fine, usi db.eval per assicurarti che il tuo codice sia eseguito direttamente sul server, altrimenti, finirai per andare a prendere Entrambe le collezioni al cliente che possono rallentare molto le cose. –