获取mongodb子文档中元素的索引,该子文档是一个对象数组

时间:2017-09-29 15:51:16

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我有一个像这样的mongodb示例对象,

{
"_id" : ObjectId("5937cbec0de02a0004cb57b3"),
"usernameAsEntered" : "logan",
"platform" : "ios",
"lastName" : "Jackman",
"firstName" : "Hugh",
"androidDevices" : [],
"iosDevices" : [],
"isAgeRestrictedCategories" : [],
"role" : "celeb",
"updatedAt" : ISODate("2017-09-19T16:36:11.356Z"),
"createdAt" : ISODate("2017-06-07T09:48:28.269Z"),
"lastUpdated" : ISODate("2017-06-09T10:36:59.448Z"),
"active" : false,
"birthday" : null,
"notificationCount" : 0,
"points" : 0,
"topicLocked" : [ 
    "msfk", 
    "flirty", 
    "dirty", 
    "mahesh_test"
],
"hashfriends" : [],
"blockedList" : [],
"verifiedCeleb" : true,
"celebParticipants" : [ 
    {
        "user" : ObjectId("57ab51940a993203009d8506"),
        "lastPlayed" : ISODate("2017-08-28T18:01:07.763Z"),
        "_id" : ObjectId("59897f4b55acb50010f80741"),
        "totalQuizAnswered" : 10,
        "scoreInPercentage" : 90,
        "score" : 9
    }, 
    {
        "user" : ObjectId("577e223df34e570300de1872"),
        "lastPlayed" : ISODate("2017-09-18T08:52:33.872Z"),
        "_id" : ObjectId("5996d7a01e146200104fc7da"),
        "totalQuizAnswered" : 10,
        "scoreInPercentage" : 90,
        "score" : 9
    }, 
    {
        "user" : ObjectId("59bf6d53373af70011475b6d"),
        "lastPlayed" : ISODate("2017-09-18T07:55:42.794Z"),
        "_id" : ObjectId("59bf7ba5373af70011475b9d"),
        "totalQuizAnswered" : 10,
        "scoreInPercentage" : 80,
        "score" : 8
    }, 
    {
        "user" : ObjectId("5979f782be0970001abdc93b"),
        "lastPlayed" : ISODate("2017-08-29T15:51:37.758Z"),
        "_id" : ObjectId("59a584bba8ed1400100b8b1d"),
        "totalQuizAnswered" : 7,
        "scoreInPercentage" : 100,
        "score" : 7
    }, 
    {
        "user" : ObjectId("5755981ae2565d0300be2b4d"),
        "lastPlayed" : ISODate("2017-08-25T03:27:38.653Z"),
        "_id" : ObjectId("5988924e809e050010bf7011"),
        "totalQuizAnswered" : 10,
        "scoreInPercentage" : 70,
        "score" : 7
    }, 
    {
        "user" : ObjectId("571759ac1f86f003002dacfa"),
        "lastPlayed" : ISODate("2017-09-05T09:01:56.949Z"),
        "_id" : ObjectId("59ae677aaf24fa001083eeb3"),
        "totalQuizAnswered" : 10,
        "scoreInPercentage" : 60,
        "score" : 6
    }, 
    {
        "user" : ObjectId("599a88a41e17140010eca45a"),
        "lastPlayed" : ISODate("2017-08-22T09:25:29.592Z"),
        "_id" : ObjectId("599bf8184ff8d70010ef3167"),
        "totalQuizAnswered" : 10,
        "scoreInPercentage" : 40,
        "score" : 4
    }, 
    {
        "user" : ObjectId("58e72582e8b311000448ac22"),
        "lastPlayed" : ISODate("2017-08-07T18:40:13.364Z"),
        "_id" : ObjectId("5988b39555acb50010f806f1"),
        "totalQuizAnswered" : 5,
        "scoreInPercentage" : 60,
        "score" : 3
    }, 
    {
        "user" : ObjectId("58e72580e8b311000448ac1d"),
        "lastPlayed" : ISODate("2017-08-07T18:10:20.652Z"),
        "_id" : ObjectId("598899c1809e050010bf7017"),
        "totalQuizAnswered" : 7,
        "scoreInPercentage" : 43,
        "score" : 3
    }, 
    {
        "user" : ObjectId("5979f33abe0970001abdc91d"),
        "lastPlayed" : ISODate("2017-08-29T07:15:35.251Z"),
        "_id" : ObjectId("599b45cf4ff8d70010ef311c"),
        "totalQuizAnswered" : 2,
        "scoreInPercentage" : 100,
        "score" : 2
    }, 
    {
        "user" : ObjectId("59885cda809e050010bf6f99"),
        "lastPlayed" : ISODate("2017-08-07T17:33:21.426Z"),
        "_id" : ObjectId("59889921809e050010bf7014"),
        "totalQuizAnswered" : 2,
        "scoreInPercentage" : 100,
        "score" : 2
    }, 
    {
        "user" : ObjectId("59bf75c7373af70011475b91"),
        "lastPlayed" : ISODate("2017-09-19T16:36:11.336Z"),
        "_id" : ObjectId("59c1469c49e8650011ec8655"),
        "totalQuizAnswered" : 7,
        "scoreInPercentage" : 29,
        "score" : 2
    }, 
    {
        "user" : ObjectId("58e72580e8b311000448ac1e"),
        "lastPlayed" : ISODate("2017-08-07T11:44:45.299Z"),
        "_id" : ObjectId("59885299809e050010bf6f78"),
        "totalQuizAnswered" : 2,
        "scoreInPercentage" : 50,
        "score" : 1
    }, 
    {
        "user" : ObjectId("59bf49b6373af70011475aa6"),
        "lastPlayed" : ISODate("2017-09-18T04:22:58.904Z"),
        "_id" : ObjectId("59bf4a22373af70011475aab"),
        "totalQuizAnswered" : 1,
        "scoreInPercentage" : 100,
        "score" : 1
    }, 
    {
        "user" : ObjectId("5980872c1ab7740010e1982f"),
        "lastPlayed" : ISODate("2017-08-01T13:56:44.261Z"),
        "_id" : ObjectId("5980889c1ab7740010e1983e"),
        "totalQuizAnswered" : 1,
        "scoreInPercentage" : 100,
        "score" : 1
    }, 
    {
        "user" : ObjectId("59bb532f7b920a0011415034"),
        "lastPlayed" : ISODate("2017-09-15T04:15:29.500Z"),
        "_id" : ObjectId("59bb53e17b920a001141503b"),
        "totalQuizAnswered" : 1,
        "scoreInPercentage" : 0,
        "score" : 0
    }, 
    {
        "user" : ObjectId("59bb62c57b920a001141509a"),
        "lastPlayed" : ISODate("2017-09-15T05:23:10.433Z"),
        "_id" : ObjectId("59bb63be7b920a001141509d"),
        "totalQuizAnswered" : 1,
        "scoreInPercentage" : 0,
        "score" : 0
    }
],
"friends" : [],
"meta" : {
    "totalInvites" : 0,
    "totalFriends" : 0
},
"isDeleted" : false,
"__v" : 298,
"avatarUrl" : "https://1.soompi.io/wp-content/uploads/2015/10/hugh-jackman.jpg",
"lastActivity" : null,
"lastNudged" : ISODate("2016-04-25T06:46:38.267Z")

}

celebParticipants数组可能存储了数万个对象。

如果我想从用户B的celebParticipants数组中获取说用户A的索引,那么使用user参数实现它的最佳方法是什么,即ObjectId也是对它的外键引用如上所述。

我尝试过使用类似的东西,

let index = await models.User.aggregate([
  {'$match': {_id: mongoose.Schema.Types.ObjectId(req.params.id)}},
  {
    '$project':
       {
         'index': { '$indexOfArray': [ "$celebParticipants", 
          //can't just put in userId 
          mongoose.Schema.Types.ObjectId(userId)] },
       }
   }
]);

但这不起作用,因为用户是对象的一部分,而数组不是仅用户ID的数组。有没有办法实现这一目标,除了获取所有数据,然后迭代它,或使用mapreduce。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

这对我来说在猫鼬之外起作用;尝试它的大小。注意添加._id因为你需要匹配子字段celebParticipants._id而不是数组:

db.foo.aggregate([
{$project: {"idx": {"$indexOfArray": ["$celebParticipants._id", your mongoose objectid thing]}}}
]);