MongoDB достаточно уникальный идентификатор — Безопасно ли использовать $pop для удаления элементов массива в mongo db?

#php #mongodb

#php #mongodb

Вопрос:

Я обеспокоен использованием $ pop для удаления элементов массива (встроенного документа) в mongodb по двум основным причинам:

  1. Я не знаю, является ли порядок массива статическим. Возможно ли, чтобы массив был возвращен / сохранен в другом порядке?
  2. Что, если другой пользователь удалит индекс с меньшим или равным значением до того, как я удалю свой? Это привело бы к удалению неправильных данных.

Я знаю, что могу использовать $ pull, но проблема в том, что мне, возможно, придется использовать весь встроенный объект для определения критерия, я хочу иметь возможность использовать какой-то «достаточно уникальный» (это может быть совсем другой вопрос) идентификатор для использования при работе со встроенными объектами, и его положение в массиве кажется логичным выбором.

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

  1. Добавляйте новый экземпляр MongoId к каждому встроенному объекту во время вставки. Проблема с этим теперь заключается в том, что функция $ set не вставляет дублирующуюся запись. Вам пришлось бы проверять наличие дубликатов перед вставкой.
  2. json_encode новая запись, затем md5 хэширует эту строку json. Это может быть лучшим решением, потому что это гарантирует, что идентификатор уникален для этой записи, но если вы попытаетесь вставить ту же запись, она действительно останется той же, поэтому $ set проигнорирует ее.

Итак, я предполагаю, что мой вопрос состоит из двух частей: безопасно ли использовать $ pop при удалении элементов из массива. Если нет, какова наилучшая практика добавления достаточно уникальных идентификаторов во встроенные документы?

(может иметь значение, что я использую PHP, а может и не иметь)

Ответ №1:

Для 1 порядок массива не изменится, если вы будете манипулировать им надлежащим образом.

Для 2 вы можете использовать стратегию «Обновить, если она актуальна» (оптимистичная блокировка): http://www.mongodb.org/display/DOCS/Atomic Operations#AtomicOperations-«UpdateifCurrent» Добавьте в свой документ поле версии, которое вы будете увеличивать при каждой модификации (Doctrine MongoDB ODM может сделать это за вас).

Комментарии:

1. В hainsight мой вопрос был введен в заблуждение. pop может удалить только первый или последний элемент. Вы можете отменить настройку элемента по его положению в массиве, но это просто установит его в значение null, поэтому вам сразу же придется извлекать нулевой элемент. Тем не менее, не могли бы вы, пожалуйста, объяснить, что вы подразумеваете под «хорошим способом» манипулирования массивом? Мне нравится ваша идея стратегии «Обновить, если она актуальна».

2. По-хорошему, я имею в виду, что порядок не будет изменен, за исключением случаев, когда вы явно отменяете или перетасовываете его.

3. Между моментом, когда вы извлекаете документ, и моментом, когда вы собираетесь удалить элемент, документ мог быть изменен. Элемент может быть вставлен в начало вашего массива, и вы собираетесь удалить поврежденный элемент. Итак, добавьте поле версии, увеличивайте его при каждом изменении и, когда вы обновляете свой документ с помощью unset, укажите версию в критерии поиска. Если документ был изменен, обновление завершится ошибкой.