简体   繁体   English

限制$ lookup mongo上的字段

[英]Limiting fields on $lookup mongo

I have a Mongo object with the below schema. 我有一个具有以下架构的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" : []
}

The 'author' and 'participant' fields are foreign key references to another collection with the below schema. “作者”和“参与者”字段是具有以下架构的另一个集合的外键引用。

{
"_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")
}

I need to run an aggregate on the first collection and limit the number of objects in the quizzes subdocument, and also sort it on the updatedAt timestamp. 我需要在第一个集合上运行聚合,并限制测验子文档中的对象数量,并且还要在updatedAt时间戳上对其进行排序。

I also want to populate author and participant inside each element in quizzes array, from the users collection. 我也想在用户集合的测验数组中的每个元素中填充作者和参与者。 However, I'm having a hard time retrieving the fields I need, ie only username, firstName, lastName, _id, meta and active. 但是,我很难检索需要的字段,即仅用户名,firstName,lastName,_id,meta和active。

I managed upto this point. 我设法做到这一点。

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]
  }}
}
])

However, this is the response I desire. 但是,这是我想要的回应。

{
"_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" : []
}

Can the lookup be done after the initial projection, and how do I limit fields. 可以在初始投影之后进行查找,以及如何限制字段。 Any help will be appreciated. 任何帮助将不胜感激。 Thanks 谢谢

I won't familiarize myself enough with your schema to work out the entire pipeline, but If I could generalize a bit: 我不会对您的架构足够熟悉,无法完成整个流程,但是如果可以概括一下:

Yes, the $lookup can be done after a $project operation. 是的,可以在$project操作之后完成$lookup You can have multiple $project operations (indeed multiple of any operation) in an aggregation. 聚合中可以有多个$project操作(实际上是任何操作的多个)。

A $lookup operation could be followed by a $project operation to normalize your results in the following fashion: $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
}},

Since $lookup returns results in an array, the above example uses $arrayElemAt to get the first element and project the desired properties one by one. 由于$lookup返回数组中的结果,因此上面的示例使用$arrayElemAt获取第一个元素并逐个投影所需的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM