2013-11-06 17 views
6

У меня есть две существующие коллекции и вам нужно заполнить третью, основываясь на сравнении между двумя существующими. Две коллекции, которые должны быть сравнены имеет следующую схему:Сравнение документов между двумя коллекциями MongoDB

Settings collection 
{ 
    "Identifier":"ABC123", 
    "C":"1", 
    "U":"V", 
    "Low":116, 
    "High":124, 
    "ImportLogId":1 
} 

Data collection 
{ 
    "Identifier":"ABC123", 
    "C":"1", 
    "U":"V", 
    "Date":"11/6/2013 12AM", 
    "Value":128, 
    "ImportLogId": 1 
} 

Я новичок в MongoDB и NoSQL в целом, так что я имею трудное время схватывая, как это сделать. SQL будет выглядеть как этот

SELECT s.Identifier, r.ReadValue, r.U, r.C, r.Date 
FROM Settings s 
JOIN Reads r 
    ON s.Identifier = r.Identifier 
    AND s.C = r.C 
    AND s.U = r.U 
WHERE (r.Value <= s.Low OR r.Value >= s.High) 

В этом случае с помощью выборки данных, я хотел бы вернуть запись, так как значение из коллекции данных больше, чем высокое значение из коллекции настройки. Возможно ли это с помощью запросов Mongo или уменьшения карты, или это плохая структура коллекции (то есть, возможно, все это должно быть в одной коллекции)?

Еще несколько дополнительных примечаний: Коллекция настроек должна иметь только 1 запись на «Идентификатор». Сбор данных будет иметь много записей на «Идентификатор». Этот процесс потенциально может сканировать сотни тысяч документов за один раз, поэтому рассмотрение ресурсов несколько важно

+1

Почему вы не используете команду diff? – myildirim

+3

Это та вещь, на которой MongoDB действительно не предназначен. – WiredPrairie

ответ

3

Невозможно выполнить такую ​​операцию, используя MongoDB. Если вы хотите BAD, как вы можете использовать такой код:

db.settings.find().forEach(
    function(doc) { 
     data = db.data.find({ 
      Identifier: doc.Idendtifier, 
      C: doc.C, 
      U: doc.U, 
      $or: [{Value: {$lte: doc.Low}}, {Value: {$gte: doc.High}}] 
     }).toArray(); 
     // Do what you need 
    } 
) 

, но не ожидаем, что он будет выполнять даже отдаленно, как хорошо, как любой приличной РСУБД.

Вы можете восстановить свои схемы и вставлять документы из сбора данных, как это:

{ 
    "_id" : ObjectId("527a7f4b07c17a1f8ad009d2"), 
    "Identifier" : "ABC123", 
    "C" : "1", 
    "U" : "V", 
    "Low" : 116, 
    "High" : 124, 
    "ImportLogId" : 1, 
    "Data" : [ 
     { 
      "Date" : ISODate("2013-11-06T00:00:00Z"), 
      "Value" : 128 
     }, 
     { 
      "Date" : ISODate("2013-10-09T00:00:00Z"), 
      "Value" : 99 
     } 
    ] 
} 

Он может работать, если количество вложенного документа низкое, но если честно работа с массивами документов далеко не приятный опыт , Даже не упоминайте, что вы можете легко достигнуть ограничения размера документа с ростом размера массива данных.

Если этот тип операций типичен для вашего приложения, я бы рассмотрел использование другого решения. Насколько мне нравится MongoDB, он хорошо работает только с определенными типами данных и шаблонами доступа.

1

Без концепции JOIN вы должны изменить свой подход и денормализовать.

В вашем случае, похоже, что вы выполняете проверку журнала данных. Мой совет представляет собой набор настроек циклов и каждый из них использует оператор findAndModify, чтобы установить флаг проверки на записи данных, которые соответствуют; после этого вы можете просто использовать оператор find для сбора данных, фильтруя новый флаг.

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