Проблема с индексацией позиционных операторов MongoDB с использованием python и pymongo

#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. Спасибо, Джо, это сработало и решило мою проблему! Ты потрясающая! Я был почти там, но мне не хватало некоторых знаний о том, как работают эти фильтры массивов и позиционные операторы. Я узнал кое-что новое!