【问题标题】:MongoDB data model and update strategyMongoDB数据模型及更新策略
【发布时间】:2013-11-14 10:43:22
【问题描述】:

我有一个名为 Players 的 MongoDB 集合

_id, name, stats[ { stName, stValue, stCountC } ]

我每天都会更新每个玩家的各种统计数据,但只会在找到新值时更新统计值(即new.stCount > existing.stCountC)。我的总体想法是将 stats 数组限制为每个唯一 stName 的 2 个对象——一个用于当前值,一个用于上一个值。因此,举例来说,假设我找到一个计数为 6 的新统计信息,我的查询和更新过程将从 -

db.players.findOne({ name: "JSmith",
                     stats: { $elemMatch: { stName: "Avg", stCountC: 5 } } })

如果上面的查询返回一个文档,那么我更新如下-

1) 获取 JSmith 的 stValue,其中 stName = "Avg"stCountP = 4 -

db.players.findOne({ name: "JSmith", stats: { stName: "Avg", stCountP: 4 } },
                   { stats.$.stValue })

2) 将此值插入到我的 StatsHistory 集合中,该集合包含单个统计类型的每个玩家的所有历史值 -

db.statshistory.update({ Name: "JSmith", StatName: "Avg" },
                       { $addToSet : { oldValues : { stValue: <val>, stCount: 4 } } })

3) 更新我的 Players 收藏 -

db.players.update({ Name: JSmith },
                  { $push: { stats: { stName: "Avg", stValue: "98", stCountC: 6 } }
                    $pull: { stats: { stName: "Avg", stCountP: 4 } } })

db.players.update({ name: "JSmith", stats.stName: "Avg", stats.stCountC: 5 },
                  { $rename: { "stats.stCountC": "stats.stCountP" } })

我将展示来自 Players 集合的当前统计值的数据网格(即每个玩家一行,每个统计名称一列)。我还将有显示统计值趋势的视图,并假设我将使用 MongoDB 的聚合函数从我的 StatsHistory 集合中返回这些。

问题:上述数据模型和查找/更新过程看起来合乎逻辑吗?

我显然是 MongoDB 的新手,因此对于任何语法错误或上述内容似乎完全不适合我的需求,我深表歉意。非常感谢任何反馈!

已解决: 感谢idbentley 提供以下建议。它帮助我使用async.js 设计了以下数据库更新程序。请注意,数据模型略有变化——Players 集合现在只保存最新的统计值,每次尝试更新传递都会更新主记录上的LastScan 日期戳,并且每次统计更新都会提供一个日期戳LastUpdate。统计计数仍用于检查返回的统计信息是否较新。此过程还确保将任何新玩家/统计数据更新到集合中。

async.series([
  function(cb){ db.statshistory.update({ Name: <name>, StatName: <statname> },
                                       { $set : { LastScan: new Date() }},
                                       { upsert: true },
                                       function() { cb(); });
  }
  ,function(cb){ db.statshistory.update({ Name: <name>, StatName: <statname>, OldValues: { $not : { $elemMatch : { StCount: <statcount> }}}},
                                        { $push : { OldValues: { LastUpdate: new Date(), StCount: <statcount>, StValue: <statvalue> }}},
                                        function() { cb(); });
  }
  ,function(cb){ db.players.update({ Name: <name> },
                                   { $set : { LastScan: new Date() }},
                                   { upsert: true },
                                   function() { cb(); });
  }
  ,function(cb){ db.players.update({ Name: <name> },
                                   { $pull : { Stats: { StName: <statname>, StCount: { $ne: <statcount> }}}},
                                   function() { cb(); });
  }
  ,function(cb){ db.players.update({ Name: <name>, Stats: { $not : { $elemMatch : { StName: <statname>, StCount: <statcount> }}}},
                                   { $push : { Stats: { LastUpdate: new Date(), StCount: <statcount>, StValue: <statvalue> }}},
                                   function() { cb(); });
  }]
  ,function() { console.log('update complete'); }
)

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    我认为您可能使事情变得比必要的复杂。

    我对您的要求的理解:

    1. 每个玩家都有一些随时间变化的统计数据。
    2. 我们应该保持球员统计数据的完整历史记录,但大多数情况下我们只需要当前和以前的统计数据

    如果我理解正确,那么我会稍微改变一下。

    首先,我将在嵌入的stats 文档中添加一个current 标志。

    然后您的工作流程更改为:

    db.statshistory.update( { Name: <name>, StatName: <statname> },
        { $addToSet : { oldValues : { <statobj> } } } );
    
    db.player.update( { Name: <name>, stats:
        { $elemMatch: { stName: <statname>} } },
        { $pull: { current: false } } );
    
    db.player.update( {Name: <name>, stats: 
        { $elemMatch: { stName: <statname>, current: true } } },
        { $set: { stats.current: false } } );
    
    db.player.update({Name: <name>},
        { $addToSet: { <statobj>, current: true } });
    

    因为这使用了多次更新,所以在多线程环境中无法正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多