【问题标题】:MongoDB positional operators index issue using python and pymongo使用 python 和 pymongo 的 MongoDB 位置运算符索引问题
【发布时间】:2021-12-31 01:17:06
【问题描述】:

我正在学习 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.$': 'Test 1' }},
    array_filters=[{ 'name.albumName': 'Album 1' }]
  )

execute 函数中的值是从表单中引入的,但我只是硬编码了这篇文章的值。

期待
根据上面的查询,我正在寻找一个具有“歌曲 2”的对象,然后使用数组过滤器来获取其所在的正确 专辑对象,然后使用位置运算符来获取 index 并将值更改为“Test 1”。

如果我通过引用数据库对专辑索引和歌曲索引进行硬编码,它可以工作,但我需要它们是动态的,因为用户将选择专辑、歌曲标题,然后为歌曲提供新值。

实际
查询完成后,“Song 1”已更新为“Test 1”而不是“Song 2”。
如果我要尝试:

 artistcol.update_one(
    { 'albums.songs': 'Song 3' },
    { '$set': { 'albums.$[name].songs.$': 'Test 2' }},
    array_filters=[{ 'name.albumName': 'Album 2' }]
  )

它会将“Song 4”更新为“Test 2”。

我目前的理解
看起来,无论过滤查询找到什么索引,位置运算符 ($) 都指向同一个索引。

我唯一需要弄清楚的是如何定位歌曲中的特定数组元素并将其值更改为用户输入的任何值。

我查看了很多关于 MongoDB 的文档,尽我所能理解,并尝试了不同的方法,但我没有任何运气。

任何帮助将不胜感激,我不知道从哪里开始。 :)

【问题讨论】:

    标签: python arrays mongodb nested pymongo


    【解决方案1】:

    位置运算符将引用顶级数组中与查询匹配的第一个元素。

    在问题的查询中,$ 指的是匹配的专辑,即

     {
         'albumName': Album 1
         'songs': [ Song 1, Song 2]
     }, 
    

    使用数组过滤器选择嵌套数组的元素,如:

    .update(
      {"albums.songs": "Song 2"},
      {$set: {"albums.$.songs.$[song]": "Tested"}},
      {arrayFilters: [{song: "Song 2"}]
    })
    

    Playground

    【讨论】:

    • 谢谢乔,这有效并解决了我的问题!你太棒了!我快到了,但对这些数组过滤器和位置运算符的工作原理缺乏一些了解。我学到了新东西!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 2022-01-14
    • 2021-03-24
    相关资源
    最近更新 更多