MongoDB用于存储大量指标/分析数据的方法

时间:2011-04-19 06:55:57

标签: database-design mongodb statistics analytics

我们计划使用MongoDB存储大量分析数据,例如观看次数和点击次数。我不确定在MongoDB中构建文档以帮助查询和减少数据库大小的最佳方法。

我们需要再次记录页面名称,客户端和操作类型的操作。理想情况下,我们需要下降年/月/日/小时水平的统计数据,我们不需要或关心每秒或每分钟的观看次数。虽然这个文档结构看起来还不错,但我知道有100个游客可以生成100个新文档。

{ 
  "_id" : ObjectId( "4dabdef81a34961506040000" ),
  "pagename" : "Hello",
  "action" : "view",
  "client" : "client-name",
  "time" : Date( "Mon Apr 18 07:49:28 2011" )
}

是否有使用$incCapped Collections的最佳做法?

2 个答案:

答案 0 :(得分:16)

更新回答

在mongo shell中共同攻击:

use pagestats;

// a little helper function
var pagePerHour = function(pagename) {
    d = new Date();
    return {
        page : pagename,
        year: d.getUTCFullYear(),
        month: d.getUTCMonth(),
        day : d.getUTCDate(),
        hour: d.getUTCHours(),
    }
}

// a pageview happened
db.pagestats.update(
    pagePerHour('Hello'),
    { $inc : { views : 1 }},
    true ); //we want to upsert

// somebody tweeted our page twice!
db.pagestats.update(
    pagePerHour('Hello'),
    { $inc : { tweets : 2 }},
    true ); //we want to upsert

db.pagestats.find();
// { "_id" : ObjectId("4dafe88a02662f38b4a20193"),
//   "year" : 2011, "day" : 21, "hour" : 8, "month" : 3,
//   "page" : "Hello",
//   "tweets" : 2, "views" : 1 }

// 24 hour summary 'Hello' on 2011-4-21
for(i = 0; i < 24; i++) {
    //careful: days (1-31), month (0-11) and hours (0-23)
    stats = db.pagestats.findOne({ page: 'Hello', year: 2011, month: 3, day : 21, hour : i})
    if(stats) {
        print(i + ': ' + stats.views + ' views')
    } else {
        print(i + ': no hits')
    };
}

根据您要跟踪的方面,您可以考虑添加更多集合(例如,以用户为中心的跟踪集合)。希望有所帮助。

另见

Blogpost about Analytics Data

答案 1 :(得分:1)

我不会太担心太空,Mongo在这方面可以无限​​扩展,增加更多空间会相当便宜。

需要注意的一件事是,如果你不断更新文档,它的大小会增长,这意味着Mongo最终需要在索引中为它找到一个新的位置。如果您有大量文档正在更新并且大小不断增加,Mongo将需要大量复制这些文档,这可能会显着减慢速度。当然这一切都取决于你期望的流量。

根据我的经验,使用简单的文档格式,您不需要更新文档,以后可能会使查询变得复杂,但您可以使用map / reduce来获取您想要的任何信息,而不管您的文档是什么结构(地图缩小非常灵活,只要有足够的经验,你可以做任何事情)。