代码之家  ›  专栏  ›  技术社区  ›  Medet Tleukabiluly

正确的Mongoose子文档关系

  •  1
  • Medet Tleukabiluly  · 技术社区  · 6 年前

    我有个模特

    const userSchema = Schema({
      username: String
    })
    
    const invitationSchema = Schema({
      decision: String,
      user: {
        type: Schema.ObjectId,
        ref: 'User'
      }
    })
    
    const groupSchema = Schema({
      name: String,
      invitations: [{
        type: Schema.ObjectId,
        ref: 'Invitation'
      }]
    })
    

    所以基本模型看起来像

    group {
      name
      invitations [
         user {
           username
         }
      ]
    }
    

    作为用户,我想获取我有邀请的所有组

    const user = getContextUser()
    Group.find({
      'invitations.user': user._id
    })
    

    但它似乎不起作用,我可以用一个属性组来表示 Group 中的架构 Invitation 模型,但我想要好的方法

    如何获取用户有邀请的所有组

    不要看下面这个,这是我在JSON中的实际模型表示,以防万一。

    // GROUP
    {
      "_id": ObjectId("5b3901dd9a8c0e6790af4ee8"),
      "image": {
        "filename": "8547aa2a-d16c-4da7-8d51-6c9bf8038037.jpg",
        "width": 236,
        "height": 156
      },
      "geolocation": {
        "coordinates": [-152.1997, -24.7718],
        "type": "Point"
      },
      "invitations": [
        ObjectId("5b3901dd9a8c0e6790af4eea"),
        ObjectId("5b3901dd9a8c0e6790af4eeb"),
        ObjectId("5b3901dd9a8c0e6790af4eec"),
        ObjectId("5b3901dd9a8c0e6790af4eed"),
        ObjectId("5b3901dd9a8c0e6790af4eee"),
        ObjectId("5b3901dd9a8c0e6790af4eef"),
        ObjectId("5b3901dd9a8c0e6790af4ef0")
      ],
      "messages": [],
      "title": "id in magnam",
      "description": "Cupiditate doloremque sunt placeat beatae et ex rerum nisi voluptate. Aliquam hic voluptas quas iure assumenda rerum aut. Quisquam vero beatae odit aut ut quod magnam.",
      "created_at": ISODate("2018-07-01T16:31:25.237Z"),
      "created_by": ObjectId("5b3901dc9a8c0e6790af4ee1"),
      "color": "#347303",
      "require_people_decision": true,
      "is_public": true,
      "start_date": ISODate("2019-03-18T20:05:03.116Z"),
      "end_date": ISODate("2019-03-18T20:05:03.116Z"),
      "location": "25498 Berniece Prairie",
      "__v": 1
    }
    
    // INVITATION
    {
      "_id": ObjectId("5b3901dd9a8c0e6790af4eea"),
      "created_at": ISODate("2018-07-01T16:31:25.348Z"),
      "have_seen": false,
      "user": ObjectId("5b3901dc9a8c0e6790af4ee0"),
      "__v": 0
    }
    
    // USER 
    {
      "_id": ObjectId("5b3901dc9a8c0e6790af4ee0"),
      "avatar": {
        "filename": "d438befb-2ea3-4582-b6bf-b8dd3b9bcf66.jpeg",
        "width": 200,
        "height": 200
      },
      "phone": "5556106679",
      "password": "$2b$10$mbx9Yhj5mAKyVxwmxcumaepXYkCTiF/9VM2KJRARZkPOVN300pKc.",
      "version": 1,
      "friends": [],
      "__v": 0
    }
    1 回复  |  直到 6 年前
        1
  •  1
  •   Ashh    6 年前

    您可以尝试低于聚合

    Group.aggregate([
      { "$lookup": {
        "from": Invitations.collection.name,
        "let": { "invitations": "$invitations" },
        "pipeline": [
          { "$match": { "$expr": { "$in": [ "$_id", "$$invitations" ] } } }
        ],
        "as": "invitations"
      }},
      { "$match": { "invitations.user": user._id } }
    ])
    

    或者这个

    Group.aggregate([
      { "$lookup": {
        "from": Invitations.collection.name,
        "let": { "invitations": "$invitations" },
        "pipeline": [
          { "$match": {
            "user": user._id,
            "$expr": { "$in": [ "$_id", "$$invitations" ] }
          }}
        ],
        "as": "invitations"
      }},
      { "$match": { "invitations.user": user._id } }
    ])
    

    最后一个我认为是最好的选择 User 收集

    User.aggregate([
      { "$match": { "_id": user._id }},
      { "$lookup": {
        "from": Groups.collection.name,
        "let": { "userId": "$_id" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$created_by", "$$userId" ] }}}
        ],
        "as": "groups"
      }}
    ])