MongoDB:将 id 数组映射到对象,同时通过聚合函数保留顺序a

问题描述 投票:0回答:1

我正在使用 MongoDB 创建播放列表制作器。我有两个单独的收藏:

播放列表

{
  "_id": {
    "$oid": "65e7a3006b0209462d08a5f5"
  },
  "playlist_name": "name of playlist",
  "user_id": {
    "$oid": "65e3544e6b0209462d87f905"
  },
  "time": {
    "$date": "2024-03-05T17:56:00.286Z"
  },
  "tracks": [
    {
      "$oid": "65e7a2bd6b0209462d07d1d4"
    }
  ]
}

曲目

{
  "_id": {
    "$oid": "65e7a2bd6b0209462d07d1d4"
  },
  "track_id": "500h8jAdr7LvzzXlm1qxtK",
  "album_name": "From The Album Of The Same Name",
  "analysis": {
    "danceability": 0.393,
    "energy": 0.588,
    "key": 9,
    "loudness": -6.68,
    "mode": 0,
    "speechiness": 0.0613,
    "acousticness": 0.345,
    "instrumentalness": 0,
    "liveness": 0.134,
    "valence": 0.728,
    "tempo": 203.145,
    "analysis_url": "https://api.spotify.com/v1/audio-analysis/500h8jAdr7LvzzXlm1qxtK",
    "duration_ms": 186333,
    "time_signature": 4
  },
  "artist_name": "Pilot",
  "spotify": {
    "track_id": "500h8jAdr7LvzzXlm1qxtK",
    "uri": "spotify:track:500h8jAdr7LvzzXlm1qxtK",
    "track_href": "https://api.spotify.com/v1/tracks/500h8jAdr7LvzzXlm1qxtK"
  },
  "track_name": "Magic"
}

我想要有这样的输出,但函数要保留轨道数组的当前顺序:

{
  "_id": {
    "$oid": "65e7a3006b0209462d08a5f5"
  },
  "playlist_name": "songs-for-events",
  "user_id": {
    "$oid": "65e3544e6b0209462d87f905"
  },
  "time": {
    "$date": "2024-03-05T17:56:00.286Z"
  },
  "tracks": [
    {
      "_id": {
        "$oid": "65e7a2bf6b0209462d07d8a9"
      },
      "track_id": "4wkQmYpAaMe41Rc3sYZ7Vz",
      "album_name": "18 Months",
      "analysis": {
        "danceability": 0.71,
        "energy": 0.882,
        "key": 4,
        "loudness": -2.932,
        "mode": 0,
        "speechiness": 0.0595,
        "acousticness": 0.00777,
        "instrumentalness": 0.00771,
        "liveness": 0.294,
        "valence": 0.875,
        "tempo": 128.016,
        "analysis_url": "https://api.spotify.com/v1/audio-analysis/4wkQmYpAaMe41Rc3sYZ7Vz",
        "duration_ms": 232800,
        "time_signature": 4
      }
  ]
}

这是我当前的查询:

[
    {
        '$lookup': {
            'from': 'tracks', 
            'localField': 'tracks', 
            'foreignField': '_id', 
            'as': 'tracks'
        }
    }, {
        '$project': {
            'tracks.track_name': 1, 
            'tracks.artist_name': 1, 
            'tracks.album_name': 1, 
            'tracks.track_id': 1, 
            'user_id': 1, 
            'playlist_name': 1
        }
    }
]

我使用 PyMongo 包中的 MongoClient 进行聚合查询。

我尝试使用 $lookup、$addField、$sort 和许多其他聚合函数来让它工作。

mongodb mongodb-query pymongo aggregate-functions
1个回答
0
投票

是的,目前您的

$lookup
阶段将覆盖
tracks
数组字段,并且不保留原始
tracks
数组中元素的顺序。

在这种情况下,我建议使用另一个字段来存储 tracks 集合中的链接/参考轨道数组 (

linkedTracks
)。然后,您需要迭代现有的
tracks
数组,并通过
linkedTracks
运算符将每个元素转换为
$map
数组中的映射文档。

db.playlists.aggregate([
  {
    "$lookup": {
      "from": "tracks",
      "localField": "tracks",
      "foreignField": "_id",
      "as": "linkedTracks"
    }
  },
  {
    $set: {
      tracks: {
        $map: {
          input: "$tracks",
          as: "t",
          in: {
            $first: {
              $filter: {
                input: "$linkedTracks",
                cond: {
                  $eq: [
                    "$$t",
                    "$$this._id"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$project": {
      "tracks.track_name": 1,
      "tracks.artist_name": 1,
      "tracks.album_name": 1,
      "tracks.track_id": 1,
      "user_id": 1,
      "playlist_name": 1
    }
  }
])

演示@Mongo Playground

© www.soinside.com 2019 - 2024. All rights reserved.