Похоже, что вы (/ I) не можете иметь как upsert, так и array element update operation.Обновить элемент, если позиция не указана с помощью Upsert
Если вы (питон):
findDct = {
"_id": ObjectId("535e3ab9c36b4417d031402f"),
'events.ids': '176976332'
}
print col.update(findDct, {"$set" : {"events.$.foo": "bar"} }, upsert=True)
Он выбросит:
pymongo.errors.DuplicateKeyError: insertDocument :: caused by :: 11000 E11000
duplicate key error index: test.col.$_id_ dup key: { : ObjectId('535e3ab9c36b4417d031402f') }
Это происходит потому, что «_id», конечно, индекс и Монго пытается вставить документ как новый так как запрос на поиск выходит из строя на его 'events.ids': '176976332'
(cheat).
Возможно ли обновить неизвестный элемент в массиве с помощью upsert True/how?
Хммм, только если '' 'принимается командой' updates', что если ваша вторая часть что-то вроде: '{" q ": {" _id ": ObjectId (" 535e3ab9c36b4417d031402f "), 'events.ids' : '176976332'}, "u": {"$ set": {"events. $. Foo": "bar"}}} '? То, что мне удалось (без большого количества), - это сначала '$ set' с' upsert = false', и если это не будет '$ addToSet' (как и при первом обновлении). Теперь нужно измерить, что лучше (как для ресурсов сервера, так и для латентности): используйте массовый API с всегда 2 запросами для каждого вложенного документа или проверьте, не сработает ли $ set с позиционным $, и поэтому используйте $ addToSet. – Diolor
@Diolor Что-то вроде этого, но если вы хотите использовать позиционные обновления с одинаковой сортировкой или «большой» конструкцией, то это должна быть последняя попытка. Поймите, что если элемент не существует в массиве, тогда любой «upsert» ** будет ** создавать новую запись. И указанное значение '_id' в запросе приводит к ошибке повторяющегося ключа. Понимаю? –
Правда. Ну, это зависит от ваших потребностей, если это может стать опасным или нет. И если вы уверены, что документы всегда существуют (в моем случае), нет смысла использовать upsert. Понял. Спасибо – Diolor