首页 > 解决方案 > Mongodb 聚合 - 在嵌套数组中使用 $addFields 来获取真/假

问题描述

我一直在尝试使用嵌套数组中的附加字段取回数据$addFields

数据是:

{
  "show_id": 1,
  "ext1_id": 126790,
  "ext2_id": 44275,
  "show_title": "Some Big title name",
  "poster_url": "https://cdn.something.com/media/cover/o65bBCMVI.jpg",
  "description": "show description",
  "year": 2021,
  "episodes": [
    {
      "episode_title": "episode title 1",
      "episode_number": "01",
      "version": null,
      "file_id": "BAACAgUAAx0EYN2eLQADKWGOO8WclqGSBG6Kdy0DkRTAbLgGAALMAgACvj7BVnkS-frrNBz8HgQ",
      "unique_id": "AgADzAIAAr4-wVY",
      "message_id": 41,
      "added_by": "bot",
      "watched_by": [919205468, 1778357657],
      "timestamp": "2021-11-12T15:32:46.172302"
    },
    {
      "episode_title": "Episode title 2",
      "episode_number": "02",
      "version": null,
      "file_id": "BAACAgUAAx0EYN2eLQADKmGOO9QAAZCDz6lonoW1R5zPUM9sVAACOAQAApgFAVdhA3c9xoF0oB4E",
      "unique_id": "AgADOAQAApgFAVc",
      "message_id": 42,
      "added_by": "bot",
      "watched_by": [919205468],
      "timestamp": "2021-11-12T15:33:01.053049"
    },
    {
      "episode_title": "episode title 3",
      "episode_number": "03",
      "version": null,
      "file_id": "BAACAgUAAx0EYN2eLQADK2GOO9zX4pgK7d1ERd5BeQkvvobSAAKaBAAC2tNJVwYVsJ_OGprTHgQ",
      "unique_id": "AgADmgQAAtrTSVc",
      "message_id": 43,
      "added_by": "bot",
      "watched_by": [919205468],
      "timestamp": "2021-11-12T15:33:08.862887"
    }
  ],
  "alt_titles": ["alt title", "ALT TITLE", "Alt-Title"],
  "is_airing": true,
  "added_by": "bot",
  "timestamp": "2021-11-12T15:32:45.298797"
}

所以基本上,我试图user_watchedepisodes列表中添加一个字段,以便它通过检查列表中是否user_id存在watched_by再次返回列表中的列表来返回 True / False episodes

我也不希望watched_by在结果中返回。

我期待这样的事情:

{
  "show_id": 1,
  "ext1_id": 126790,
  "ext2_id": 44275,
  "show_title": "Some Big title name",
  "poster_url": "https://cdn.something.com/media/cover/o65bBCMVI.jpg",
  "description": "show description",
  "year": 2021,
  "episodes": [
    {
      "episode_title": "episode title 1",
      "episode_number": "01",
      "version": null,
      "file_id": "BAACAgUAAx0EYN2eLQADKWGOO8WclqGSBG6Kdy0DkRTAbLgGAALMAgACvj7BVnkS-frrNBz8HgQ",
      "unique_id": "AgADzAIAAr4-wVY",
      "message_id": 41,
      "added_by": "bot",
      "user_watched": true,
      "timestamp": "2021-11-12T15:32:46.172302"
    },
    {
      "episode_title": "Episode title 2",
      "episode_number": "02",
      "version": null,
      "file_id": "BAACAgUAAx0EYN2eLQADKmGOO9QAAZCDz6lonoW1R5zPUM9sVAACOAQAApgFAVdhA3c9xoF0oB4E",
      "unique_id": "AgADOAQAApgFAVc",
      "message_id": 42,
      "added_by": "bot",
      "user_watched": true,
      "timestamp": "2021-11-12T15:33:01.053049"
    },
    {
      "episode_title": "episode title 3",
      "episode_number": "03",
      "version": null,
      "file_id": "BAACAgUAAx0EYN2eLQADK2GOO9zX4pgK7d1ERd5BeQkvvobSAAKaBAAC2tNJVwYVsJ_OGprTHgQ",
      "unique_id": "AgADmgQAAtrTSVc",
      "message_id": 43,
      "added_by": "bot",
      "user_watched": true,
      "timestamp": "2021-11-12T15:33:08.862887"
    }
  ],
  "alt_titles": ["alt title", "ALT TITLE", "Alt-Title"],
  "is_airing": true,
  "added_by": "bot",
  "timestamp": "2021-11-12T15:32:45.298797"
}

我在 pymongo 中尝试了以下代码:

db.data_col.aggregate([        
    {'$sort'     : { 'timestamp' : -1 } },
    {'$facet'    : {
        "metadata": [ { "$count": "total" } ],
        "data": [ 
            {'$addFields': {
                    'episodes.user_watched': 
                        {'$cond': [
                            {
                                '$in': [
                                    919209968,
                                    "$episodes.watched_by"
                                ]
                            },
                            True,
                            False
                        ]
                    }
                }},
            
            { "$skip": offset }, { "$limit": limit },
            { '$project' : {"episodes.watched_by":0} } ,
        ]
    }}
])

user_watched但即使列表user_id中存在,我也得到了每个字段 False watched_by。和返回的数据

标签: mongodbaggregation-framework

解决方案


询问

  • 在剧集上映射,检查数组中的user(1778357657)inwatched_by并添加字段 true/false
  • 删除了 watch_by 字段

*你的查询看起来不同我猜你做了更多的事情,但这会产生预期的输出

*您的代码不起作用,因为“$episodes.watched_by”是一个包含所有watched_by 数组的数组,$map每个数组都单独检查。

测试代码在这里

db.collection.aggregate([
  {
    "$set": {
      "episodes": {
        "$map": {
          "input": "$episodes",
          "in": {
            "$mergeObjects": [
              "$$this",
              {
                "user_watched": {
                  "$in": [
                    1778357657,
                    "$$this.watched_by"
                  ]
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    "$set": {
      "episodes.watched_by": "$$REMOVE"
    }
  }
])

推荐阅读