2015-03-24 5 views
0

Это мой final Структура документа. Я нахожусь на mongo 3.0.MongoDb вставить или добавить встроенный документ

{ 
    _id: "1", 
    stockA: [ { size: "S", qty: 25 }, { size: "M", qty: 50 } ], 
    stockB: [ { size: "S", qty: 27 }, { size: "M", qty: 58 } ] 
    } 

Я случайно добавление элементов внутри stockA или stockB коллекций. Я хотел бы придумать запрос, который будет удовлетворять следующие правила:

  1. Если item не существует - создать весь документ и вставить элемент в stock A or B коллекции.
  2. Если item существует, но stock A or B коллекция отсутствует создать stock коллекция и добавьте element внутри коллекция.
  3. если item есть и stock коллекция есть только приложить element внутри коллекция.

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

Если да, не могли бы вы помочь мне найти требуемый запрос.

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

Спасибо за помощь!

+0

А как насчет полей 'details' и' category'? – styvane

+0

@ Майкл, игнорируйте их пока. Позволяет делать это только для коллекций. В принципе, у меня есть только '_id' и набор коллекций внутри документа. –

+2

Вы продолжаете использовать слово «коллекция», но то, что вы на самом деле означаете, это «массив». Может ли это быть правдой? Пожалуйста, попробуйте использовать правильную терминологию, или вы путаете и других, и себя. Иерархия сущностей в MongoDB: одна база данных имеет много коллекций, одна коллекция имеет много документов, один документ может иметь много полей, массивов и поддокументов, массив или поддокумент может содержать больше полей, массивов и поддокументов. – Philipp

ответ

1

Оператор вы ищете $addToSet или $push в сочетании с upsert:true.

Оба оператора могут принимать несколько пар ключ/значение. Затем он будет работать отдельно на каждой клавише. Оба будут создавать массив, если он еще не существует, и в любом случае добавит значение.

Разница в том, что $ addToSet сначала проверит, существует ли идентичный элемент в массиве. Когда производительность является проблемой, имейте в виду, что MongoDB должен выполнить линейный поиск, чтобы сделать это. Поэтому для очень больших массивов $ addToSet может стать довольно медленным.

Параметр upsert:true функции обновления приведет к созданию документа, если он не найден.

+0

Спасибо за подробный ответ. –

1

Вы можете использовать метод update с опцией upsert, который создаст новый документ, если ни один документ не соответствует критериям запроса.

db.collection.update({ "_id": 1 }, 
    { 
     "$push" : { 
      "stockB" : { 
          "size" : "M", 
          "qty" : 51 
      }, 
      "stockA" : { 
          "size" : "M", 
          "qty" : 21 
      } 
     } 
    }, 
    { "upsert": true } 
) 
+0

Почему 'findAndModify' вместо просто' update'? OP не указывает, что им нужен документ после его восстановления. – Philipp

+0

Спасибо, оба ответа поразительны. –