#mongodb #mongoose #mongodb-query
Вопрос:
Я пытаюсь обновить несколько элементов в массиве в определенном документе, где у меня есть индексы элементов, которые необходимо обновить, только если какой-то ключ не существует.
Ссылка на игровую площадку MongoDB
Предположим, у меня есть документ:
{
"key": 1,
"questions": [
{
"text": "first",
},
{
"text": "second",
},
{
"text": "third",
"answered": "balloon",
},
],
},
Я хочу обновить 2-й и 3-й элементы (индексы 2 и 3) новым полем «ответ», но обновите только те, в которых уже нет поля «ответ».
Вот запрос, с которым я справился до сих пор:
db.collection.update({
"key": 1,
},
{
$set: {
"questions.1.answered": "second answer",
"questions.2.answered": "third answer",
}
}
)
Это обновление как 2-го, так и 3-го индексов и установка «ответа» для них обоих. Но я хочу пропустить «3-й», поскольку у него уже был «ответный» ключ.
Как я могу добиться этого исключения?
Может быть, что-то в строках ArrayFilters?
Ожидаемый результат:
{
"key": 1,
"questions": [
{
"text": "first",
},
{
"text": "second",
"answered": "second answer", //Added field
},
{
"text": "third",
"answered": "balloon", //Should not update as it already had "answered"
},
],
},
Ответ №1:
Вам нужно необязательное обновление, поэтому я использовал конвейерное обновление.
Возможно, вы можете сделать это только с помощью операторов обновления, но приведенное ниже также работает нормально.
Запрос
- в «данные» поместите массив ответов и соответствующие индексы
- сопоставьте индексы вопросов
(0 1 2 ...)
- проверьте, есть ли индекс в тех, которые необходимо изменить
- если у них нет ответа, получите ответ
update({"key" : 1},
[{"$set":
{"data": {"answers": ["index1-a", "index2-a"], "indexes": [1, 2]}}},
{"$set":
{"questions":
{"$map":
{"input": {"$range": [0, {"$size": "$questions"}]},
"in":
{"$let":
{"vars": {"question": {"$arrayElemAt": ["$questions", "$this"]}},
"in":
{"$cond":
[{"$and":
[{"$in": ["$this", "$data.indexes"]},
{"$eq": [{"$type": "$question.answered"}, "missing"]}]},
{"$mergeObjects":
["$question",
{"answered":
{"$arrayElemAt":
["$data.answers",
{"$indexOfArray": ["$data.indexes", "$this"]}]}}]},
{"$arrayElemAt": ["$questions", "$this"]}]}}}}}}},
{"$unset": ["data"]}])