简体   繁体   English

使用流星中的mongo聚合来总计解锁/锁定的集合

[英]Using mongo aggregate in meteor to total unlocked/locked in collection

So, I have one collection that stores docs related to a user with a structure like: 因此,我有一个集合可以存储与用户相关的文档,其结构如下:

{_id: "hofjew233332j4", userId: "fhewojfw34324", achievementUnlocked: true };

What I want to do is use the aggregate and underscore to be able to group the docs by user id and then calculate what percentage of their records have unlocked set to true such that a resulting doc would look like: 我想做的是使用聚合和下划线来按用户ID对文档进行分组,然后计算将其未锁定记录的百分比设置为true,这样生成的文档将如下所示:

{_id: "fhewojfw34324(userId)", unlockPercentage: 40 (achievementUnlocked: true / all docs) }

Would I be able to do this while only retrieving the documents once? 我可以只检索一次文档就能做到吗?

First group by count achievementUnlocked true count and used after that in project to calculate percentage as using below aggregation: 第一组按计数achievementUnlocked true计数,然后在项目中使用以下计数来计算percentage ,方法如下:

db.collectionName.aggregate([{
    "$group": {
        "_id": "$userId",
        "achievementUnlockedTrueCount": {
            "$sum": {
                "$cond": {
                    "if": {
                        "$eq": ["$achievementUnlocked", true] //count achievementUnlocked = true count 
                    },
                    "then": 1,
                    "else": 0
                }
            }
        },
        "totalCount": {
            "$sum": 1 // get total count of grouped documents 
        }
    }
}, {
    "$project": {
        "unlockPercentage": {
            "$multiply": [{
                "$divide": ["$achievementUnlockedTrueCount", "$totalCount"] //used this in project to caculate %
            }, 100]
        }
    }
}]).pretty()

I would personally not even bother with aggregation here as the data would seem trivial. 我个人甚至不会在这里进行汇总,因为数据似乎微不足道。 It would be far more efficient to maintain an array of "locked" and "unlocked" achievements per user and/or "game" data. 维护每个用户和/或“游戏”数据的一系列“锁定”和“解锁”成就将更为有效。

Take a document like this: 取得像这样的文件:

{
    "_id": "hofjew233332j4", 
    "userId": "fhewojfw34324",
    "gameId": "v3XWHHvFSHwYxxk6H",
    "achievementsCount": 5,
    "locked": ["One","Two","Four","Five"],
    "lockedCount": 4,
    "unlocked": ["Three"]
    "unlockedCount": 1
}

So you would initialize per user and "game" here with all "locked" achievements normally, but in this case we will show one already within "unlocked". 因此,您通常会使用所有“锁定”的成就在此处初始化每个用户和“游戏”,但是在这种情况下,我们将显示“解锁”中已经存在的成就。 Also note the "count" fields reflect the number of entries present in each array. 另请注意,“ count”字段反映每个阵列中存在的条目数。

To "unlock" another achievement, then you would simply perform an update to remove from the "locked" array and insert into the "unlocked" array, all while maintaining the "count" values: 要“解锁”另一项成就,则只需执行更新以从“锁定”数组中删除并插入到“解锁”数组中,同时保持“计数”值不变:

Achievements.update(
   { 
       "userId": "fhewojfw34324",
       "gameId": "v3XWHHvFSHwYxxk6H",
       "locked": "Four",
       "unlocked": { "$ne": "Four" }
   },
   {
       "$push": { "unlocked": "Four" },
       "$pull": { "locked": "Four" },
       "$inc": {
           "lockedCount": -1,
           "unlockedCount": 1
       }
   }
)

Which alters the document to this state: 这会将文档更改为以下状态:

{
    "_id": "hofjew233332j4", 
    "userId": "fhewojfw34324",
    "gameId": "v3XWHHvFSHwYxxk6H",
    "achievementsCount": 5,
    "locked": ["One","Two","Five"],
    "lockedCount": 3,
    "unlocked": ["Three","Four"]
    "unlockedCount": 2
}

It's a very simple pattern to follow as each update maintains the correct values and data. 这是一个非常简单的模式,因为每次更新都会维护正确的值和数据。 If you wanted information such as a "percentage" then this is a simple matter of: 如果您需要诸如“百分比”之类的信息,那么这很简单:

Achievements.aggregate([
    { "$project": {
        "userId": 1,
        "gameId": 1,
        "percentUnlocked": { "$divide": [ "$unlockedCount", "$achivementsCount" ] }
])

Or just apply that math in client code instead. 或者只是将数学应用到客户端代码中。

This model also makes "real" aggregations you might want to do a lot simplier, and with a lot more scope to information. 该模型还使您可能希望做的“真实”聚合要简单得多,并且具有更大的信息范围。 Plus, it's much more efficient to calculate as you go, than to require something to "add up" the data as a separate process. 另外,进行计算的效率要比要求将数据“累加”为一个单独的过程要有效得多。

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

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