Предположим, у меня есть эта запись в коллекции:
{
"_id" : ObjectId("5c56160e4b6929067972b4c8"),
"name" : "car",
"attributes" : [
{
"color" : "blue",
"qty" : 10
}
]
}
Код, который я реализовал для upsert, выглядит следующим образом:
def insert(item: Item): Future[Option[Item]] = {
val selector = BSONDocument("name" -> item.name, "attributes" -> BSONDocument("$elemMatch" -> Json.toJson(item.attributes.head)))
val updateModifier = BSONDocument(
f"$$push" -> BSONDocument("attributes" -> Json.toJson(item.attributes.head)))
itemsCollection.flatMap(
_.findAndUpdate(selector, updateModifier, upsert = true)
.map(_.result[Item])
)
}
Однако при выполнении этого кода коллекция обновляется следующим образом:
{
"_id" : ObjectId("5c56160e4b6929067972b4c8"),
"name" : "car",
"attributes" : [
{
"color" : "blue",
"qty" : 10
},
{
"color" : "blue",
"qty" : 10
}
]
}
Обратите внимание, что добавляется повторяющаяся запись. Этого не должно происходить согласно логике upsert.
Как я могу предотвратить вставку повторяющейся записи? Что не так с кодом?
После консультации с людьми на канале MongoDB, по-видимому, это НЕ тривиальная вещь, т.е. вставка во встроенный документ. Mongo — безумно сложный инструмент для работы, когда документ имеет хотя бы намек на сложность. Плоские документы в порядке. Результирующие запросы просты. Но как только структура данных становится сложной, запросы становятся очень сложными для написания.

Сначала попробуйте в mongoshell