2014-11-25 5 views
1

Учитывая следующему дБОбновления на подмножестве вложенных документов в MongoDB

{ 
    "type":"s", 
    "disp":[ 
     { 
      "quantity":1, 
      "date":20141109 
     }, 
     { 
      "quantity":1, 
      "date":20141110 
     }, 
     { 
      "quantity":1, 
      "date":20141111 
     } 
    ] 
}, 
{ 
    "type":"d", 
    "disp":[ 
     { 
      "quantity":1, 
      "date":20141109 
     }, 
     { 
      "quantity":0, 
      "date":20141110 
     }, 
     { 
      "quantity":1, 
      "date":20141111 
     } 
    ] 
} 

я выполнить запрос, чтобы получить «тип» с количеством терки затем 0 для набора дат

db.test.find({ "$and" : [ 
    { "disp" : { "$elemMatch" : { "quantity" : { "$gt" : 0 }, "date" : 20141109 } } }, 
    { "disp" : { "$elemMatch" : { "quantity" : { "$gt" : 0 }, "date" : 20141110 } } } 
] },{"type":1}) 

Я получаю тип «s», тогда я хочу уменьшить на 1 только количество для дат, которые я только что запросил

Я пробовал разные виды запросов на обновление, но я смог изменить только одно поле количества.

Как я могу это сделать атомным путем? Если это невозможно, вы можете посоветовать мне способ структурирования моих данных для запроса и атомического обновления количества для определенных дат?

ответ

1

Вы можете обновить только единый соответствующий под-документ в MongoDb, даже если несколько поддокументов соответствуют запросу. В настоящее время это ограничение.

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

Вам необходимо использовать $inc и позиционное обновление $ операторов.

var dates = [20141109,20141110]; 
dates.forEach(function(date){ 
db.test.update({"type":"s","disp.date":date}, 
        {$inc:{"disp.$.quantity":1}}) 
}) 

Ответ на ваши вопросы:

атомарно количество обновлений для конкретных дат

Согласно документации,

$ вкл является атомарной операцией в пределах единый документ.

Предложение:

н способ структурировать мои данные для запроса

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

{ 
     "quantity":0, 
     "date":20141110 
    }, 
    { 
     "quantity":1, 
     "date":20141110 
    } 
+0

Интересно, если запрос документ, изменить его в памяти и обновлять его в целом не лучше, чем несколько обновлений ... BTW дублированные даты опечатка, я редактировал его;) – Edo

+0

Если количество соответствующих поддоменов значительно велико, тогда да, лучше справиться с этим на стороне клиента. Модифицировать и обновлять все вспомогательные документы, иначе это нормально. – BatScream

+0

У меня проблема с параллелизмом. Я должен избегать двух совпадающих совпадений запросов, потому что первый из них частично обновляет отдельные даты. В противном случае мне придется управлять откатом ... – Edo