首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >mongoDB -通过另一个文档字段添加自定义字段,并进行分页

mongoDB -通过另一个文档字段添加自定义字段,并进行分页
EN

Stack Overflow用户
提问于 2022-06-14 18:58:47
回答 2查看 104关注 0票数 1

我有user schemainvitation schema。当用户搜索用户时,我希望返回具有属性invited的对象的数组。

代码语言:javascript
运行
复制
const InvitationSchema = new Schema<IInvitation>(
    {
        sender: {
            type: Schema.Types.ObjectId,
            ref: 'user'
        },
        receiver: {
            type: Schema.Types.ObjectId,
            ref: 'user'
        }
    }
)
const IUserSchema = new Schema<IUser>(
    {
        email: {
            type: String,
        },
        invitedUsers: [
            {
                type: Schema.Types.ObjectId,
                ref: 'user'
            }
        ]
    }
)

我的问题是:

  1. 有3个ids用户- userId1,userId2,userId3
  2. User1向User2发出邀请。因此,当前db变成:
代码语言:javascript
运行
复制
user1:{
  id:userId1,
  invitedUsers:[userId2]
}

invitation1:{
  id:someId,
  sender:userId1,
  receiver:userId2
}
  1. 在这里,User1向服务器发出用户搜索请求并接收:
代码语言:javascript
运行
复制
users:[
  {
     id:userId2,
     invited:true
  },
  {
     id:userId3,
     invited:false
  },
]

我还想对用户进行分页,但它不是当前问题的目标。

我尝试了一些使用聚合$addFields的变体,但是没有任何效果。另一种方法是增加10个查询,因为每个页面的用户是10个,这当然是个坏主意。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-06-15 18:52:08

这是个不错的问题。一种选择是使用$lookup来完成它。

  1. 这里的前4个步骤是关于分页,在排序、跳过、限制和删除请求搜索的用户之后,只返回所需的文档数。
  2. 然后,我们使用$lookup`添加requestingUserId的详细信息,包括我们所选文档中每个文档上的邀请用户ids列表。
  3. 现在剩下的就是检查每个文档是否包含在我们从请求用户那里获得的id中。
代码语言:javascript
运行
复制
db.users.aggregate([
  {$match: {id: {$ne: requestingUserId}}},
  {$sort: {id: 1}},
  {$skip: 1},
  {$limit: 2},
  {$addFields: {invitedBy: requestingUserId }},
  {
    $lookup: {
      from: "users",
      localField: "invitedBy",
      foreignField: "id",
      as: "invited"
    }
  },
  {$set: {invited: {$first: "$invited"}}},
  {
    $project: {
      invited: {$cond: [{$in: ["$id", "$invited.invitedUsers"]}, true, false] },
      id: 1, _id: 0
    }
  }
])

看看它如何在操场实例上工作

还可以通过使用$lookup管道来只带来所需的部分来提高性能:

代码语言:javascript
运行
复制
db.users.aggregate([
  {$match: {id: {$ne: requestingUserId}}},
  {$sort: {id: 1}},
  {$skip: 1},
  {$limit: 2},
  {
    $lookup: {
      from: "users",
      let: {myId: "$id"},
      pipeline: [
        {$match: {id: "userId1"}},
        {$project: {res: {$cond: [{$in: ["$$myId", "$invitedUsers"]}, true, false]}}}
      ],
      as: "invited"
    }
  },
  {$project: {invited: {$first: "$invited.res"}, id: 1, _id: 0}}
])

看看它如何在操场示例.查找-管道上工作

票数 1
EN

Stack Overflow用户

发布于 2022-06-15 08:05:16

如果要检查invitedUsers数组是否具有一定长度,则返回true,否则为false,则可以使用聚合完成这一操作。

代码语言:javascript
运行
复制
User.aggregate([
  {
    $project: {
      _id: 1,
      invitedUsers: {
        $cond: [
          { $gt: [{ $size:"$invitedUsers" }, 0] },
          true,
          false,
        ],
      }
    }
  }
])

探索聚合这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72622107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档