2016-04-25 4 views
0

Я ищу какой-то подобный пример, но не нашел что-то хорошее.MongoDB update complex document

{ 
 
    "_id" : ObjectId("571dea148234534308a290e"), 
 
    "user" : "myusername", 
 
    "duration" : "", 
 
    "test_details" : [ 
 
     { 
 
      "test" : "New", 
 
      "test_id" : "0", 
 
      "comments" : "will be some text", 
 
      "text" : "" 
 
     }, 
 
     { 
 
      "test" : "**to change value here**", 
 
      "test_id" : "1", 
 
      "comments" : "will be some text", 
 
      "text" : "**to change value here**" 
 
     }, 
 
     { 
 
      "test" : "New", 
 
      "test_id" : "2", 
 
      "comments" : "will be some text", 
 
      "text" : "" 
 
     }, 
 
     { 
 
      "test" : "New", 
 
      "test_id" : "3", 
 
      "comments" : "will be some text", 
 
      "text" : "" 
 
      "sub_test_details" : [ 
 
       { 
 
        "56eed334534566ac5668ca18" : [ 
 
         { 
 
          "sub_test" : "New", 
 
          "sub_test_id" : "0", 
 
          "sub_comments" : "will be some text", 
 
          "sub_text" : "" 
 
         }, 
 
         { 
 
          "sub_test" : "New", 
 
          "sub_test_id" : "1", 
 
          "sub_comments" : "will be some text", 
 
          "sub_text" : "" 
 
         }, 
 
         { 
 
          "sub_test" : "New", 
 
          "sub_test_id" : "2", 
 
          "sub_comments" : "will be some text", 
 
          "sub_text" : "" 
 
         } 
 
        ] 
 
       }, 
 
       { 
 
        "56eed3b1f37d66ac5668ca19" : [ 
 
         { 
 
          "sub_test" : "New", 
 
          "sub_test_id" : "0", 
 
          "sub_comments" : "will be some text", 
 
          "sub_text" : "" 
 
         }, 
 
         { 
 
          "sub_test" : "New", 
 
          "sub_test_id" : "1", 
 
          "sub_comments" : "will be some text", 
 
          "sub_text" : "" 
 
         }, 
 
         { 
 
          "sub_test" : "**to change value here**", 
 
          "sub_test_id" : "2", 
 
          "sub_comments" : "will be some text", 
 
          "sub_text" : "**to change value here**" 
 
         } 
 
        ] 
 
       } 
 
      ] 
 
     }, 
 
     { 
 
      "test" : "New", 
 
      "test_id" : "4", 
 
      "comments" : "will be some text", 
 
      "text" : "" 
 
     } 
 
    ], 
 
}

И вопросы:

  1. Что запрос обновить текст = "завершено успешно" и тест = "Готово", где _id ": ObjectId (" 571dea148234534308a290e ") .test_id = 1.

  2. Что такое запрос для обновления sub_text =" Sub Completed Successfully "и sub_test =" Sub Done ", где _ Идентификатор»: ObjectId. ("571dea148234534308a290e") test_details.test_id = 3.sub_test_details.56eed3b1f37d66ac5668ca19.sub_step_id = 2

В моем случае я буду получать идентификатор, test_id, exam_num (56eed3b1f37d66ac5668ca19) , sub_test_id будут параметрами, чтобы найти подходящее место для обновления. Размер элементов массива не всегда постоянный. Поэтому я использую id, чтобы точно указать, какой элемент я ищу.

Благодаря

ответ

0

Метод обновления должен сделать это для вас, вы должны использовать $ addToSet, чтобы гарантировать, что никакие дубликаты не вдаваться в массив данного ИО и upsert: верно обновить существующие документы с таким же идентификатором. Ниже должен работать

db.tests.update(
    {_id" : ObjectId("571dea148234534308a290e"}, 
    {$addToSet: 
     { test_details: 
      {test_id: "0", 
      test: "Done", 
      text: "Completed Successfully" 
    }}}, 
    {upsert: true} 
); 
1

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

db.test.update({"_id": ObjectId("571dea148234534308a290e"), "test_details.test_id": "1"}, {"$set": {"test_details.$.test": "Done", "test_details.$.text": "Completed Succesfully"}}) 

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

{ 
    "test" : "New", 
    "test_id" : "3", 
    "text" : "" 
    "sub_test_details" : { 
     "56eed334534566ac5668ca18" : { 
      "0": { 
       "sub_test" : "New", 
       "sub_text" : "" 
      }, 
      "1": { 
       "sub_test" : "New", 
       "sub_text" : "" 
      }, 
      "2": { 
       "sub_test" : "New", 
       "sub_text" : "" 
      } 
     }, 
     "56eed3b1f37d66ac5668ca19" : { 
      "0": { 
       "sub_test" : "New", 
       "sub_text" : "" 
      }, 
      "1": { 
       "sub_test" : "New", 
       "sub_text" : "" 
      }, 
      "2": { 
       "sub_test" : "**to change value here**", 
       "sub_text" : "**to change value here**" 
      } 
     } 
    } 
} 

и запрос будет выглядеть следующим образом:

db.test.update({"_id": ObjectId("571e32c0907445669f11037e"), "test_details.test_id": "3"}, {"$set": {"test_details.$.sub_test_details.56eed334534566ac5668ca18.0.sub_test": "Done", "test_details.$.sub_test_details.56eed334534566ac5668ca18.0.sub_text": "Completed Succesfully"}}) 

Также см this вопрос, где подобные проблемы обсуждено