使用 pymongo 从多个更高级别的数组对象聚合嵌套数组对象

Posted

技术标签:

【中文标题】使用 pymongo 从多个更高级别的数组对象聚合嵌套数组对象【英文标题】:Aggregate nested array objects from multiple higher level array objects using pymongo 【发布时间】:2022-01-13 04:51:16 【问题描述】:

基本上,我有一个带有嵌套对象数组的对象数组。我想为用户 ID 为“user1”的用户获取 flashcardReversed 数组对象,其中 front 等于“2front”。

这是我的数据:

[
  
    "_id": "608642db80a36336946620aa",
    "userID": "user1",
    "title": "title2",
    "flashcardReversed": [
      
        "_id": "608d5b290e635ece6828141X",
        "front": "2front",
        "back": "2back",
        "value": "1",
      ,
      
        "_id": "608t5b290e635ece6828141Y",
        "front": "2frontReversed",
        "back": "2backReversed"
        "value": "2",
      ,
      
        "_id": "608a5b31a3f9806de253726X",
        "front": "2front2",
        "back": "2back2"
        "value": "3",
      ,
      
        "_id": "608a5b31a3f9806de253726Y",
        "front": "2frontReversed2",
        "back": "2backReversed2"
        "value": "4",
      
    ]
  ,
  
    "_id": "608642db80a36336946620aa",
    "userID": "user1",
    "title": "title3",
    "flashcardReversed": [
      
        "_id": "608d5b290e635ece6828142X",
        "front": "2front",
        "back": "2back",
        "value": "12",
      ,
      
        "_id": "608t5b290e635ece6828143Y",
        "front": "2frontReversed",
        "back": "2backReversed"
        "value": "21",
      ,
      
        "_id": "608a5b31a3f9806de253727X",
        "front": "2front2",
        "back": "2back2"
        "value": "34",
      ,
      
        "_id": "608a5b31a3f9806de253729Y",
        "front": "2frontReversed2",
        "back": "2backReversed2"
        "value": "42",
      
    ]
  ,
  
    "_id": "608642db80a36336946620aa",
    "userID": "user2",
    "title": "title4",
    "flashcardReversed": [
      
        "_id": "608d5b290e635ece6828131X",
        "front": "2front",
        "back": "2back",
        "value": "41",
      ,
      
        "_id": "608t5b290e635ece6828161Y",
        "front": "2frontReversed",
        "back": "2backReversed"
        "value": "54",
      ,
      
        "_id": "608a5b31a3f9806de253526X",
        "front": "2front2",
        "back": "2back2"
        "value": "63",
      ,
      
        "_id": "608a5b31a3f9806de253326Y",
        "front": "2frontReversed2",
        "back": "2backReversed2"
        "value": "29",
      
    ]
  ,
]

有 2 个对象的用户 ID 为“user1”,因此输出应如下所示:


    "userID": "user1"
    "flashcardReversed": [
      
        "_id": "608d5b290e635ece6828141X",
        "front": "2front",
        "back": "2back",
        "value": "1",
      ,
      
        "_id": "608d5b290e635ece6828142X",
        "front": "2front",
        "back": "2back",
        "value": "12",
      ,
    ]

是否可以使用 pymongo 编写代码?

【问题讨论】:

【参考方案1】: $match $unwind $match $group
db.collection.aggregate([
  
    "$match": 
      "userID": "user1",
      "flashcardReversed.front": "2front"
    
  ,
  
    "$unwind": "$flashcardReversed"
  ,
  
    "$match": 
      "flashcardReversed.front": "2front"
    
  ,
  
    "$group": 
      "_id": "$userID",
      "flashcardReversed": 
        "$push": "$$ROOT.flashcardReversed"
      
    
  
])

mongoplayground

带有 fastAPI 的 pymongo

@app.get("/card")
async def root():
    db = get_database()
    pipeline = [ 
         "$match":  "userID": "user1", "flashcardReversed.front": "2front"  , 
         "$unwind": "$flashcardReversed" , 
         "$match":  "flashcardReversed.front": "2front"  , 
         "$group":  "_id": "$userID", "flashcardReversed":  "$push": "$$ROOT.flashcardReversed"    
    ]
    c = list(db['card'].aggregate(pipeline))
    return "message": c

【讨论】:

以上是关于使用 pymongo 从多个更高级别的数组对象聚合嵌套数组对象的主要内容,如果未能解决你的问题,请参考以下文章

Jackson - 将内部对象列表反序列化为更高级别的列表

使用聚合和查找 mongodb 从对象数组中获取最小值

使用聚合和查找 mongodb 从对象数组中获取最小值

如何将多个 Stream 合并为更高级别的 Stream?

Pymongo 中的聚合函数

当数据非常嵌套时如何使用 $gt 聚合文档和聚合 Pymongo