MongoDB - 如何在聚合中进行子查询

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

我正在尝试向名为

friendshipStatus
的聚合添加一个字段,它确定用户是否是请求者的好友。

我有整个查询:

[
  {
    $match: (query) ? query : {}
  },
  {
    $addFields: {
      friendshipStatus: {
        $cond: {
          if: {
            $in: [vierweruserName || '', "$friends"]
          },
          then: "friend",
          else: {
            $cond: {
              if: {
                $in: [vierweruserName || '', "$friendRequests"]
              },
              then: "requested",
              else: "none"
            }
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      firstName: 1,
      lastName: 1,
      userDescription: 1,
      userName: 1,
      imgURL: 1,
      coverURL: 1,
      friendshipStatus: 1 // Include the new field in the output
    }
  },
  {
    $limit: 50
  }
]

我想修改这个

addField
阶段来检查用户名是否在请求者的
friendRequests
数组中(如果他向请求者发送了好友请求,就会发生这种情况)

{
  $addFields: {
    friendshipStatus: {
      $cond: {
        if: {
          $in: [vierweruserName || '', "$friends"]
        },
        then: "friend",
        else: {
          $cond: {
            if: {
              $in: [vierweruserName || '', "$friendRequests"]
            },
            then: "requested",
            else: "none"
          }
        }
      }
    }
  }
}

如果用户位于

friendshipStatus
文档中的
friendRequests
数组中,我希望代码还应将
viewerUserName
添加为“请求”。我想知道是否可以在
addFields
阶段进行子查询来获取viewerUserName文档然后搜索它或者是否有其他方法。

样本文件:

{
    "_id": "65034fed2153ebff85f30554",
    "userName": "minamelad232",
    "firstName": "mina",
    "lastName": "melad",
    "password": "$2b$10$Sr/cWOWwtAC9AQpHHLjFfuD3TKLIFvjd89QwgIJdz6cMB.rvWFeJy",
    "userDescription": "No description",
    "friends": ["minamelad123"],
    "friendRequests": ["markosami123"],
    "imgURL": "http://res.cloudinary.com/dik65evmf/image/upload/v1694726404/widgetUpl...",
    "coverURL": "http://res.cloudinary.com/dik65evmf/image/upload/v1694715952/widgetUpl...",
    "influence": 0,
    "feedOffset": 0,
    "commentsOffset": 0,
    "friendRequestsOffset": 0,
    "__v": 42    
}

输出示例:

{
    "userName": "minamelad232",
    "firstName": "mina",
    "lastName": "melad",
    "userDescription": "No description",
    "imgURL": "http://res.cloudinary.com/dik65evmf/image/upload/v1694726404/widgetUpload/qbegll5tmhumijplqkek.jpg",
    "coverURL": "http://res.cloudinary.com/dik65evmf/image/upload/v1694715952/widgetUpload/f61ztmyvln0c5p0ei1db.png",
    "friendshipStatus": "none"
}
javascript node.js mongodb mongoose aggregation-framework
2个回答
1
投票

鉴于这些是示例(最小)文档:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "userName": "Alex",
    "friends": [],
    "friendRequests": [
      //"may"
      
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "userName": "May",
    "friends": [],
    "friendRequests": [
      "Alex"
    ]
  }
]

如上所述,您需要搜索观看者的

friendRequests
,这需要使用
userName: vierwerUsename

自行加入收藏
  1. $lookup
    - 使用
    userName: vierwerUsename
    搜索同一集合中的文档,并将数组中的文档返回为
    viewer

  2. $addField
    - 建议使用
    $switch
    运算符来处理多个条件,而不是嵌套
    $cond
    。对于第三个条件,您应该将文档中的
    userName
    的条件匹配到
    friendRequest
    viewer
    中。

{
    $lookup: {
      from: "collection", // replace with your collection name
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: [
                vieweruserName || '',
                "$userName"
              ]
            }
          }
        }
      ],
      as: "viewer"
    }
  },
  {
    $addFields: {
      friendshipStatus: {
        $switch: {
          branches: [
            {
              case: {
                $in: [
                  vieweruserName || '',
                  "$friends"
                ]
              },
              then: "friend"
            },
            {
              case: {
                $in: [
                  vieweruserName || '',
                  "$friendRequests"
                ]
              },
              then: "requested"
            },
            {
              case: {
                $in: [
                  "$userName",
                  {
                    $getField: {
                      field: "friendRequests",
                      input: {
                        $arrayElemAt: [
                          "$viewer",
                          0
                        ]
                      }
                    }
                  }
                ]
              },
              then: "requested"
            }
          ],
          default: "none"
        }
      }
    }
  }

演示@Mongo Playground


0
投票

在当前查询中,您正在检查 $friends 数组或 $friendRequests 数组中是否存在viewerUserName,以确定friendshipStatus。如果你想检查viewerUserName是否存在于viewerUserName文档本身的friendRequests数组中,你可以修改查询如下:

[
  {
    $match: (query) ? query : {}
  },
  {
    $addFields: {
      friendshipStatus: {
        $cond: {
          if: {
            $in: [vierweruserName || '', "$friends"]
          },
          then: "friend",
          else: {
            $cond: {
              if: {
                $in: [vierweruserName || '', "$friendRequests"]
              },
              then: "requested",
              else: {
                $cond: {
                  if: {
                    $in: [vierweruserName || '', "$$ROOT.friendRequests"] // Check in viewerUserName's own friendRequests array
                  },
                  then: "requested",
                  else: "none"
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      firstName: 1,
      lastName: 1,
      userDescription: 1,
      userName: 1,
      imgURL: 1,
      coverURL: 1,
      friendshipStatus: 1 // Include the new field in the output
    }
  },
  {
    $limit: 50
  }
]

在修改后的查询中,我在第二个 $cond 表达式的 else 块内添加了一个额外的 $cond 表达式。这将检查viewerUserName 是否存在于viewerUserName 文档本身的friendRequests 数组中($$ROOT.friendRequests)。如果是,则 FriendshipStatus 将设置为“已请求”。否则,它将被设置为“无”。

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