2012-02-11 5 views
11

Im пытается «сравнить» все документы между 2 коллекциями, которые вернут только истину, и если только все документы внутри 2 коллекций будут в точности равны.Как сравнить 2 коллекции mongodb?

Я искал методы в коллекции, но не смог найти тот, который может это сделать.

я экспериментировал что-то вроде них в Монго оболочки, но не работает, как я ожидал:

db.test1 == db.test2 

или

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

Во всяком случае, им также с помощью MongoDB весна-данных в Java.

Пожалуйста, поделитесь своими мыслями! Спасибо.

+3

Использование 'db.runCommand ('dbHash')' даст вам хэши для ваших db и коллекций, из которых вы можете сравнить хэш коллекции с другим хешем коллекции. Возможно, будет легче узнать, одинаковы ли обе коллекции. – Rexford

ответ

13

Вы можете попробовать использовать mongodb eval в сочетании с вашей пользовательской функцией равенства, что-то вроде this.

Ваши методы не работают, потому что в первом случае вы сравниваете ссылки на объекты, которые не совпадают. Во втором случае нет гарантии, что to_json будет генерировать одну и ту же строку даже для одинаковых объектов.

Вместо этого, попробовать что-то вроде этого:

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

С db.eval вы убедитесь, что код будет выполняться на стороне сервера базы данных, не извлекая коллекции клиенту.

+0

Спасибо за идею. Если я правильно понимаю, у этого фактически есть 2 цикла, где 1 документ в test1 будет протестирован со всеми документами в test2 ..? Или, возможно, вы имели в виду, что в аргументе test2.find мы помещаем id объекта obj1, потому что в моем случае то, что находится в test1, должно быть в test2 с тем же идентификатором. Кроме того, им очень сложно понять, что, если test2 имеет больше документов, чем test1, или если у test1 есть больше документов, чем у test2, что в моем случае означает, что test1 и test2 не равны. Любые мысли об их обнаружении без циклов с обеих сторон коллекций? Благодаря ! – bertie

+0

Этот код проходит через обе коллекции и делает что-то, когда находит совпадение из первой коллекции во второй коллекции (или вы можете что-то сделать, когда совпадение не найдено, просто положите if (! Equals (...) Если вы просто хотите для сравнения, если обе коллекции равны, это может быть оптимизировано очень часто ... например, перед выполнением db.test1.find вы можете сравнить количество совпадений обеих коллекций, например db.test1.find(). count() == db .test2.find(). count() ... и если count не равен, нет причин для продолжения. Также, как я указал в коде, если есть какое-то свойство, о котором вы знаете (например, _id), вы (продолжение ...) –

+0

может поместить его внутри db.test2.find ({... here ...}) и ускорить поиск второго объекта). Итак, если ваши подсчеты равны, и вы никогда не входите в if (! equals (...)), тогда ваши коллекции равны ... Важно то, что в конце вы используете db.eval, чтобы убедиться, что ваш код выполняется непосредственно на сервере, в противном случае вы окажетесь получать и обе коллекции для клиента, которые могут значительно замедлить работу. –

Смежные вопросы