2014-04-03 1 views
1
I need some help updating property of embedded collection with JSON structure below  - 
    translation 
    { 
    "_id" : ObjectId("533d4c73d86b8977fda970a9"), 
    "_class" : "com.xxx.xxx.translation.domain.Translation", 
    "locales" : [ 
     { 
     "_id" : "en-US", 
     "description" : "English (United States)", 
     "isActive" : true 
     }, 
     { 
     "_id" : "pt-BR", 
     "description" : "Portuguese (Brazil)", 
     "isActive" : true 
     }, 
    { 
     "_id" : "nl-NL", 
     "description" : "Dutch (Netherlands)", 
     "isActive" : true 
    } 
    ], 
    "screens" : [ 
    { 
     "_id" : "caseCodes", 
     "dictionary" : [ 
      { 
       "key" : "CS_CAT1", 
       "parameterizedValue" : "My investigations", 
       "locale" : "en-US" 
      }, 
      { 
       "key" : "MY_INVESTIGATIONS", 
       "parameterizedValue" : "", 
       "locale" : "pt-BR" 
      }, 
     } 
     ] 
    } 

данных В приведенном выше структуре: Я хочу обновить «parameterizedValue» usinng весны-данные Монго-дб API 1.3.4, для экрана с _id = «caseCodes» и ключ = "CS_CAT1".Как обновить встроенное Монго документа с помощью пружины Монго апи

Я попытался (здесь «значения» это имя коллекции для TranslationValue массива)

 mongoOperations.updateFirst(Query.query(Criteria.where("screens._id") 
      .is("caseCodes")), new Update().push(
      "screens.dictionary.$.values", translationValue), 
      Translation.class); 

но сказал, «не может добавить массив в строку„словарь“....

Любой указатели или помочь здесь? Спасибо.

-Sanjeev

ответ

3

Есть несколько проблем, с вашей логикой, а также проблемами с вашей схемой для данного типа обновления.

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

Поскольку вам нужна определенная запись во внутреннем массиве, вам также нужно будет это сопоставить. Но «улов» говорит, что в полевом операторе будет использоваться только совпадение, поэтому вы не можете иметь оба. Форма запроса (если это было возможно работать, что он не) на самом деле было бы что-то вроде этого (родной оболочки):

db.collection.update(
    { 
     "screens._id": "caseCodes", 
     "screens.dictionary.key": "CS_CAT1" 
    }, 
    { 
     "$set": { 
      "screens.$.dictionary.$.parameterizedValue": "new value" 
     } 
    } 
) 

Теперь, когда будет «казаться» более правильным, чем то, что вы но, конечно, это не удается, потому что оператор позиционирования нельзя использовать более одного раза. Я могу просто глупо работать в этом случае, так как бывает так, что первый сопоставленный индекс массива «экранов» (который равен 0), как оказалось, точно такой же, как и требуемый индекс внутреннего элемента. Но на самом деле это просто «глупая удача».

Чтобы проиллюстрировать, что вам нужно делать с этими типами обновлений, уже знайте индексы элементов и поместите эти значения непосредственно в инструкцию обновления с помощью «точечной нотации». Таким образом, обновляя свой второй элемент «словарь» будет идти, как это:

db.collection.update(
    { 
     "screens._id": "caseCodes", 
     "screens.dictionary.key": "MY_INVESTIGATIONS" 
    }, 
    { 
     "$set": { 
      "screens.0.dictionary.1.parameterizedValue": "new value" 
     } 
    } 
) 

отметить также, что корректный оператор использовать здесь $set как вы не добавляя ни к одному из массивов, а вы хотите, чтобы изменить элемент ,

Поскольку такая точность в обновлениях вряд ли соответствует потребностям, тогда вы должны посмотреть на изменение схемы, чтобы приспособить ваши операции гораздо более удобным способом.Поэтому одна возможность заключается в том, что ваши «экраны» данные не могут, возможно, должны быть массив, и вы могли бы изменить, что в форме документа следующим образом:

 "screens" : { 
     "caseCodes": [ 
      { 
       "key" : "CS_CAT1", 
       "parameterizedValue" : "My investigations", 
       "locale" : "en-US" 
      }, 
      { 
       "key" : "MY_INVESTIGATIONS", 
       "parameterizedValue" : "", 
       "locale" : "pt-BR" 
      }, 
     ] 
    } 

Это изменило форму:

db.collection.update(
    { 
     "screens.caseCodes.key": "CS_CAT1" 
    }, 
    { 
     "$set": { 
      "screens.caseCodes.$.parameterizedValue": "new value" 
     } 
    } 
) 

Это может работать или не работать в ваших целях, но вы либо живете с ограничениями использования вложенного массива, либо каким-либо образом меняете свою схему.

+0

Спасибо, Нейл. Это - «$ set»: { "screens.0.dictionary.1.parameterizedValue": "новое значение" } –

+0

это сработало для меня. –