首页 文章

限制$ lookup mongo上的字段

提问于
浏览
0

我有一个具有以下架构的Mongo对象 .

{
    "_id" : "59fffda313d02500116e83bf::5a059c67f3ff3b001105c509",
    "quizzes" : [ 
        {
            "topics" : [ 
                ObjectId("5a05a1e1fc698f00118470e2")
            ],
            "isCorrect" : true,
            "status" : 2,
            "isUsed" : true,
            "askBack" : false,
            "isRestricted" : false,
            "rejected" : false,
            "createdAt" : ISODate("2017-11-10T12:56:01.273Z"),
            "updatedAt" : ISODate("2017-11-10T12:56:02.808Z"),
            "answerRead" : false,
            "participantAnswer" : "5a054210d74fe90011d5f5e2",
            "correctAnswer" : "5a054210d74fe90011d5f5e2",
            "question" : ObjectId("5a054210d74fe90011d5f5e0"),
            "participant" : ObjectId("59fffda313d02500116e83bf"),
            "author" : ObjectId("5a059c67f3ff3b001105c509"),
            "_id" : ObjectId("5a05a1e1fc698f00118470e1")
        }, 
        {
            "topics" : [ 
                ObjectId("5a054210d74fe90011d5f5e1")
            ],
            "isCorrect" : false,
            "status" : 2,
            "isUsed" : true,
            "askBack" : true,
            "isRestricted" : false,
            "rejected" : false,
            "createdAt" : ISODate("2017-11-10T12:57:33.910Z"),
            "updatedAt" : ISODate("2017-11-10T12:57:33.910Z"),
            "answerRead" : true,
            "correctAnswer" : "5a054210d74fe90011d5f5e2",
            "question" : ObjectId("5a054210d74fe90011d5f5e0"),
            "participant" : ObjectId("5a059c67f3ff3b001105c509"),
            "author" : ObjectId("59fffda313d02500116e83bf"),
            "_id" : ObjectId("5a05a23dfc698f00118470f5")
        }
    ],
    "participants" : [ 
        ObjectId("5a059c67f3ff3b001105c509"), 
        ObjectId("59fffda313d02500116e83bf")
    ],
    "__v" : 0,
    "skippedQuestionIds" : []
}

“作者”和“参与者”字段是具有以下模式的另一个集合的外键引用 .

{
"_id" : ObjectId("5739bcdd4fb7d8030050bc04"),
"password" : "$2a$06$4Rmiya6Vh9aENXxKoD56UOIG3ZiGNzH.Ed5lgY8aiJ4OidQPAf6wq",
"email" : "m@m.com",
"username" : "mm",
"birthday" : ISODate("2016-05-03T18:30:00.000Z"),
"lastName" : "m",
"firstName" : "m",
"devices" : [],
"role" : "user",
"updatedAt" : ISODate("2017-08-01T13:26:43.510Z"),
"createdAt" : ISODate("2016-05-16T12:28:13.063Z"),
"lastUpdated" : ISODate("2017-08-02T07:39:02.960Z"),
"active" : false,
"points" : 0,
"topicLocked" : [ 
    "flirty", 
    "dirty", 
    "mahesh_test"
],
"hashfriends" : [],
"blockedList" : [],
"friends" : [ 
    {
        "user" : ObjectId("586b6fd12631000004812a68"),
        "_id" : ObjectId("58e60399ca9a180004072089"),
        "topicExhausted" : [],
        "scoreInPercentage" : 0,
        "totalQuizAnswered" : 1,
        "isCrew" : false,
        "isFriendo" : false,
        "scoreRank" : "You’re tied 1 to 1",
        "score" : 1,
        "lastPlayed" : ISODate("2017-04-06T09:37:48.843Z")
    }
],
"meta" : {
    "totalInvites" : -3,
    "totalFriends" : 1
},
"isDeleted" : false,
"__v" : 3,
"androidDevices" : [],
"iosDevices" : [],
"isAgeRestrictedCategories" : [ 
    ObjectId("571727dde30aef0300a95725")
],
"usernameAsEntered" : "mm",
"platform" : "ios",
"celebParticipants" : [],
"lastActivity" : ISODate("2017-04-06T09:30:34.054Z"),
"lastNudged" : ISODate("2016-04-25T06:46:38.267Z")
}

我需要在第一个集合上运行聚合并限制测验子文档中的对象数量,并在updatedAt时间戳上对其进行排序 .

我还想在users集合中的quizzes数组中的每个元素中填充作者和参与者 . 但是,我很难检索到我需要的字段,即只有username,firstName,lastName,_id,meta和active .

我做到了这一点 .

db.getCollection('usergames').aggregate([{$match: {_id: "5a059c56f3ff3b001105c508::5a059c67f3ff3b001105c509"}},
{$unwind: '$quizzes'},
{$lookup: {
    "from":'users',
    "localField":'quizzes.author',
    'foreignField': '_id',
    "as": 'quizzes.author'
}},
{$unwind: '$quizzes.author'},
{$sort: {'quizzes.updatedAt': -1}},
{$group: {_id: '$_id', quizzes: {$push: '$quizzes'}}},
{$project: {
  _id: 1,
  'quizzes': {
            $slice:['$quizzes', 0, 3]
  }}
}
])

但是,这是我想要的回应 .

{
"_id" : "59fffda313d02500116e83bf::5a059c67f3ff3b001105c509",
"quizzes" : [ 
    {
        "topics" : [ 
            ObjectId("5a054210d74fe90011d5f5e1")
        ],
        "isCorrect" : false,
        "status" : 2,
        "isUsed" : true,
        "askBack" : true,
        "isRestricted" : false,
        "rejected" : false,
        "createdAt" : ISODate("2017-11-10T12:57:33.910Z"),
        "updatedAt" : ISODate("2017-11-10T12:57:33.910Z"),
        "answerRead" : true,
        "correctAnswer" : "5a054210d74fe90011d5f5e2",
        "question" : ObjectId("5a054210d74fe90011d5f5e0"),
        "author" :{
                    "_id": "59fffda313d02500116e83bf",
                    "username": "f2",
                    "lastName": "2",
                    "firstName": "f",
                    "active": false,
                    "meta": {
                         "totalInvites": 0,
                         "totalFriends": 1
                   }
          },
        "participant": {
                  "_id": "5a059c67f3ff3b001105c509",
                  "username": "chandan",
                  "lastName": "kumar",
                  "firstName": "chandan",
                  "active": false,
                  "meta": {
                     "totalInvites": 0,
                     "totalFriends": 16
                  }

     "_id" : ObjectId("5a05a23dfc698f00118470f5")
    }
],
"participants" : [ 
    ObjectId("5a059c67f3ff3b001105c509"), 
    ObjectId("59fffda313d02500116e83bf")
],
"__v" : 0,
"skippedQuestionIds" : []
}

可以在初始投影之后完成查找,以及如何限制字段 . 任何帮助将不胜感激 . 谢谢

1 回答

  • 0

    我不会完全熟悉你的模式来计算整个管道,但是如果我可以概括一下:

    是的, $lookup 可以在 $project 操作后完成 . 您可以在聚合中进行多个 $project 操作(实际上是多个操作) .

    $lookup 操作之后可能会执行 $project 操作以按以下方式规范化结果:

    {$lookup: {
        "from":'users',
        "localField":'quizzes.author',
        'foreignField': '_id',
        "as": 'authors'
    }},
    {$project: {
        'author._id': { $arrayElemAt: ['$authors._id', 0] },
        'author.username': { $arrayElemAt: ['$authors.username', 0] },
        // other fields can be projected as needed
    }},
    

    由于 $lookup 返回数组中的结果,因此上面的示例使用 $arrayElemAt 获取第一个元素并逐个投影所需的属性 .

相关问题