MongoDB运行总计,例如以前记录的聚合,直到出现值为止 [英] MongoDB running total like aggregation of previous records up until occurrance of value

查看:53
本文介绍了MongoDB运行总计,例如以前记录的聚合,直到出现值为止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在处理一系列比赛中的各种比赛事件.在游戏中,可以杀死敌人并在商店中购买物品.

I am currently dealing with a set of in-game-events for various matches. In the game it is possible to kill enemies and purchase items in a shop.

我现在试图做的是计算直到每次购买事件之前一次比赛中发生的击杀次数.

What I have been trying to do right now, is to count the number of kills that have occured in a single match up until every purchasing event.

{
    "_id" : ObjectId("5988f89ae5873exxxxxxx"),
    "gameId" : NumberLong(2910126xxx)
    "participantId" : 3,
    "type" : "ITEM_PURCHASED",
    "timestamp" : 656664 },    
{
    "_id" : ObjectId("5988f89ae5873exxxxxxx"),
    "gameId" : NumberLong(2910126xxx)
    "participantId" : 3,
    "victimId" : 9,
    "type" : "ENEMY_KILLED",
    "timestamp" : 745245 },
{
    "_id" : ObjectId("5988f89ae5873exxxxxxx"),
    "gameId" : NumberLong(2910126xxx)
    "participantId" : 3,
    "victimId" : 7,
    "type" : "ENEMY_KILLED",
    "timestamp" : 746223 },
{
    "_id" : ObjectId("5988f89ae5873exxxxxxx"),
    "gameId" : NumberLong(2910126xxx)
    "participantId" : 3,
    "type" : "ITEM_PURCHASED",
    "timestamp" : 840245 },    

这对我来说是理想的结果:

In which this is a desired outcome for me:

{
    "_id" : ObjectId("5988f89ae5873exxxxxxx"),
    "gameId" : NumberLong(2910126xxx)
    "participantId" : 3,
    "type" : "ITEM_PURCHASED",
    "timestamp" : 656664,
    "kills": 0  },
 {
    "_id" : ObjectId("5988f89ae5873exxxxxxx"),
    "gameId" : NumberLong(2910126xxx)
    "participantId" : 3,
    "type" : "ITEM_PURCHASED",
    "timestamp" : 840245 ,
     "kills": 2  }

尽管我倾向于认为这是不可能的,但是我对mongo提供的所有功能还没有经验.

Although I am inclined to think that this is quite impossible, I am not yet that experienced with all the capabilities mongo offers.

是否有一种方法可以计数直到购买事件出现之前某些值的出现次数?

Is there a way to count occurrances of certain values up until the appearance of an purchasing event?

推荐答案

尝试此聚合

  1. $match-按gameId过滤
  2. $sort-按时间戳顺序订购文件
  3. $group-累积所有与数组匹配的数据
  4. $addFields-$reduce计算杀死数,过滤并将杀死数映射到文档
  5. $unwind-平面数组以获取原始文档结构
  6. $replaceRoot-将数据移至原始结构中的顶层
  1. $match - filter by gameId
  2. $sort - order documents by timestamp
  3. $group - accumulate all matched to an array
  4. $addFields - $reduce to calculate kills, filter and map kills to document
  5. $unwind - flat array to get original document structure
  6. $replaceRoot - move data to top level as in original structure

管道

db.games.aggregate([
    {$match : {gameId : 1}},
    {$sort : {timestamp : 1}},
    {$group : {_id : "$gameId", data : {$push : "$$ROOT"}}},
    {$addFields : {data : {
        $reduce : {
            input : "$data",
            initialValue : {kills : [], data : [], count : 0},
            in : {
                count : {$sum : ["$$value.count", {$cond : [{$eq : ["$$this.type", "ENEMY_KILLED"]}, 1, 0]}]},
                data : { $concatArrays : [
                     "$$value.data", 
                     {$cond : [
                            {$ne : ["$$this.type", "ENEMY_KILLED"]}, 
                            [
                                {
                                    _id : "$$this._id",
                                    gameId : "$$this.gameId",
                                    participantId : "$$this.participantId",
                                    type : "$$this.type",
                                    timestamp : "$$this.timestamp",
                                    kills : {$sum : ["$$value.count", {$cond : [{$eq : ["$$this.type", "ENEMY_KILLED"]}, 1, 0]}]}
                                }
                            ],
                            []
                        ]}
                    ]}
                }
            }}
    }},
    {$unwind : "$data.data"},
    {$replaceRoot : {newRoot : "$data.data"}}
]).pretty()

收藏

> db.games.find()
{ "_id" : 1, "gameId" : 1, "participantId" : 3, "type" : "ITEM_PURCHASED", "timestamp" : 656664 }
{ "_id" : 2, "gameId" : 1, "participantId" : 3, "victimId" : 9, "type" : "ENEMY_KILLED", "timestamp" : 745245 }
{ "_id" : 3, "gameId" : 1, "participantId" : 3, "victimId" : 7, "type" : "ENEMY_KILLED", "timestamp" : 746223 }
{ "_id" : 4, "gameId" : 1, "participantId" : 3, "type" : "ITEM_PURCHASED", "timestamp" : 840245 }

结果

{
    "_id" : 1,
    "gameId" : 1,
    "participantId" : 3,
    "type" : "ITEM_PURCHASED",
    "timestamp" : 656664,
    "kills" : 0
}
{
    "_id" : 4,
    "gameId" : 1,
    "participantId" : 3,
    "type" : "ITEM_PURCHASED",
    "timestamp" : 840245,
    "kills" : 2
}
> 

这篇关于MongoDB运行总计,例如以前记录的聚合,直到出现值为止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆