2012-02-24 1 views
0

Я воображал Foo делает обновление на третий комментарий, comments.2.value, в то время как бар является $pull -ную, убрав первый комментарий.mongo обновление элемента массива и состояния гонок?

Если foo заканчивается первым, то третий комментарий обновляется успешно, так как индекс по-прежнему верен.

Но если бар заканчивается первым, то индекс изменился, и Foo «s comments.2.value затронет не третий комментарий больше.

Возможно ли это, и если это так, я задаюсь вопросом, существуют ли общие решения для обновления элементов массива и состояния гонок?

Спасибо!

ответ

3

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

Например,

> db.myComments.save({_id:1, 
comments:[ 
{cid:1, author:"Marc", comment:"Marc's Comment"}, 
{cid:2, author:"Mike", comment:"Mike's Comment"}, 
{cid:3, author:"Barrie", comment:"Barrie's Comment"} 
]}) 

Если мы хотим изменить комментарий Майка, но мы не обязательно знать, что он появится второй в массиве, мы можем обновить его следующим образом:

> db.myComments.update({_id:1, "comments.cid":2}, {$set:{"comments.$.comment":"Mike's NEW Comment"}}) 
> db.myComments.find().pretty() 
{ 
    "_id" : 1, 
    "comments" : [ 
     { 
      "cid" : 1, 
      "author" : "Marc", 
      "comment" : "Marc's Comment" 
     }, 
     { 
      "author" : "Mike", 
      "cid" : 2, 
      "comment" : "Mike's NEW Comment" 
     }, 
     { 
      "cid" : 3, 
      "author" : "Barrie", 
      "comment" : "Barrie's Comment" 
     } 
    ] 
} 

Мы могли бы даже изменить весь поддокумент, например, так:

> db.myComments.update({_id:1, "comments.cid":2}, {$set:{"comments.$":{cid:4, author:"someone else", comment:"A completely new comment!"}}}) 
> db.myComments.find().pretty() 
{ 
    "_id" : 1, 
    "comments" : [ 
     { 
      "cid" : 1, 
      "author" : "Marc", 
      "comment" : "Marc's Comment" 
     }, 
     { 
      "cid" : 4, 
      "author" : "someone else", 
      "comment" : "A completely new comment!" 
     }, 
     { 
      "cid" : 3, 
      "author" : "Barrie", 
      "comment" : "Barrie's Comment" 
     } 
    ] 
} 

Документальное запрос Wil l найти первое значение в массиве, которое соответствует, а «$» в документе обновления ссылается на эту позицию.

Дополнительную информацию о «$» -операторе можно найти в разделе «Оператор $ positional» в документации «Обновление». http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

Надеюсь, это даст вам представление о том, как ваше приложение может изменять значения в массиве без ссылки на их позицию. Удачи!

+0

Удивительно! Теперь я снова могу хорошо спать. Интересно, что вы подразумеваете под «теоретически возможным, если несколько приложений одновременно обращаются к базе данных», так как в моем случае у меня есть только одно приложение, но с несколькими одновременными пользователями. – bertie

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

  • Нет связанных вопросов^_^