#python #arrays #mongodb #nested #pymongo
Вопрос:
Я нахожусь в процессе изучения MongoDB и пытаюсь обновить вложенный массив песен, однако позиционный оператор, похоже, обновляет неправильный индекс.
Вот структура документа в базе данных:
{
'_id': ObjectId(...),
'artistName': Artist Name,
'recordLabel': Label Name,
'genre': Genre,
'albums': [
{
'albumName': Album 1
'songs': [ Song 1, Song 2]
},
{
'albumName': Album 2
'songs': [ Song 3, Song 4]
},
]
}
Вот функция update_one (), которую я пытаюсь выполнить:
artistcol.update_one(
{ 'albums.songs': 'Song 2' },
{ '$set': { 'albums.$[name].songs.
Значения в функции выполнения вводятся из формы, но я только что жестко закодировал значения для этого поста.
Ожидание:
Основываясь на приведенном выше запросе, я ищу объект с "Песней 2", а затем использую фильтры массива, чтобы захватить нужный объект альбома, в котором он находится, а затем позиционный оператор, чтобы захватить индекс песни и изменить значение на "Тест 1".
Если я жестко закодирую индекс альбома и индекс песни, ссылаясь на базу данных, она работает, но мне нужно, чтобы они были динамичными, потому что пользователь выберет альбом, название песни, а затем предоставит новое значение для песни.
Фактическое:
Когда запрос заканчивается, "Песня 1" была обновлена до "Тест 1", а не "Песня 2".
Если бы я попытался:
artistcol.update_one(
{ 'albums.songs': 'Song 3' },
{ '$set': { 'albums.$[name].songs.
Он обновит "Песню 4" до "Тест 2".
Что я понимаю до сих пор:
похоже, что какой бы индекс ни был найден запросом фильтра, позиционный оператор ($) ссылается на тот же индекс.
Единственное, что мне нужно выяснить, - это как настроить таргетинг на определенный элемент массива в песнях и изменить его значение на то, что ввел пользователь.
Я просмотрел много документации для MongoDB, попытался понять все, что мог, и попробовал разные вещи, но мне не повезло.
Любая помощь была бы признательна, я не знаю, куда отсюда идти. :)
Ответ №1:
Позиционный оператор будет ссылаться на первый элемент массива верхнего уровня, соответствующий запросу.
В запросе в вопросе $
указывается соответствующий альбом, т. е.
{
'albumName': Album 1
'songs': [ Song 1, Song 2]
},
Используйте фильтр массива для выбора элемента вложенного массива, например:
.update(
{"albums.songs": "Song 2"},
{$set: {"albums.$.songs.$[song]": "Tested"}},
{arrayFilters: [{song: "Song 2"}]
})
Комментарии:
1. Спасибо, Джо, это сработало и решило мою проблему! Ты потрясающая! Я был почти там, но мне не хватало некоторых знаний о том, как работают эти фильтры массивов и позиционные операторы. Я узнал кое-что новое!
: 'Test 1' }},
array_filters=[{ 'name.albumName': 'Album 1' }]
)
Значения в функции выполнения вводятся из формы, но я только что жестко закодировал значения для этого поста.
Ожидание:
Основываясь на приведенном выше запросе, я ищу объект с "Песней 2", а затем использую фильтры массива, чтобы захватить нужный объект альбома, в котором он находится, а затем позиционный оператор, чтобы захватить индекс песни и изменить значение на "Тест 1".
Если я жестко закодирую индекс альбома и индекс песни, ссылаясь на базу данных, она работает, но мне нужно, чтобы они были динамичными, потому что пользователь выберет альбом, название песни, а затем предоставит новое значение для песни.
Фактическое:
Когда запрос заканчивается, "Песня 1" была обновлена до "Тест 1", а не "Песня 2".
Если бы я попытался:
Он обновит "Песню 4" до "Тест 2".
Что я понимаю до сих пор:
похоже, что какой бы индекс ни был найден запросом фильтра, позиционный оператор ($) ссылается на тот же индекс.
Единственное, что мне нужно выяснить, - это как настроить таргетинг на определенный элемент массива в песнях и изменить его значение на то, что ввел пользователь.
Я просмотрел много документации для MongoDB, попытался понять все, что мог, и попробовал разные вещи, но мне не повезло.
Любая помощь была бы признательна, я не знаю, куда отсюда идти. 🙂
Ответ №1:
Позиционный оператор будет ссылаться на первый элемент массива верхнего уровня, соответствующий запросу.
В запросе в вопросе $
указывается соответствующий альбом, т. е.
Используйте фильтр массива для выбора элемента вложенного массива, например:
Комментарии:
1. Спасибо, Джо, это сработало и решило мою проблему! Ты потрясающая! Я был почти там, но мне не хватало некоторых знаний о том, как работают эти фильтры массивов и позиционные операторы. Я узнал кое-что новое!
: 'Test 2' }},
array_filters=[{ 'name.albumName': 'Album 2' }]
)
Он обновит «Песню 4» до «Тест 2».
Что я понимаю до сих пор:
похоже, что какой бы индекс ни был найден запросом фильтра, позиционный оператор ($) ссылается на тот же индекс.
Единственное, что мне нужно выяснить, — это как настроить таргетинг на определенный элемент массива в песнях и изменить его значение на то, что ввел пользователь.
Я просмотрел много документации для MongoDB, попытался понять все, что мог, и попробовал разные вещи, но мне не повезло.
Любая помощь была бы признательна, я не знаю, куда отсюда идти. 🙂
Ответ №1:
Позиционный оператор будет ссылаться на первый элемент массива верхнего уровня, соответствующий запросу.
В запросе в вопросе $
указывается соответствующий альбом, т. е.
Используйте фильтр массива для выбора элемента вложенного массива, например:
Комментарии:
1. Спасибо, Джо, это сработало и решило мою проблему! Ты потрясающая! Я был почти там, но мне не хватало некоторых знаний о том, как работают эти фильтры массивов и позиционные операторы. Я узнал кое-что новое!
: ‘Test 1’ }},
array_filters=[{ ‘name.albumName’: ‘Album 1’ }]
)
Значения в функции выполнения вводятся из формы, но я только что жестко закодировал значения для этого поста.
Ожидание:
Основываясь на приведенном выше запросе, я ищу объект с «Песней 2», а затем использую фильтры массива, чтобы захватить нужный объект альбома, в котором он находится, а затем позиционный оператор, чтобы захватить индекс песни и изменить значение на «Тест 1».
Если я жестко закодирую индекс альбома и индекс песни, ссылаясь на базу данных, она работает, но мне нужно, чтобы они были динамичными, потому что пользователь выберет альбом, название песни, а затем предоставит новое значение для песни.
Фактическое:
Когда запрос заканчивается, «Песня 1» была обновлена до «Тест 1», а не «Песня 2».
Если бы я попытался:
Он обновит «Песню 4» до «Тест 2».
Что я понимаю до сих пор:
похоже, что какой бы индекс ни был найден запросом фильтра, позиционный оператор ($) ссылается на тот же индекс.
Единственное, что мне нужно выяснить, — это как настроить таргетинг на определенный элемент массива в песнях и изменить его значение на то, что ввел пользователь.
Я просмотрел много документации для MongoDB, попытался понять все, что мог, и попробовал разные вещи, но мне не повезло.
Любая помощь была бы признательна, я не знаю, куда отсюда идти. 🙂
Ответ №1:
Позиционный оператор будет ссылаться на первый элемент массива верхнего уровня, соответствующий запросу.
В запросе в вопросе $
указывается соответствующий альбом, т. е.
Используйте фильтр массива для выбора элемента вложенного массива, например:
Комментарии:
1. Спасибо, Джо, это сработало и решило мою проблему! Ты потрясающая! Я был почти там, но мне не хватало некоторых знаний о том, как работают эти фильтры массивов и позиционные операторы. Я узнал кое-что новое!