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

16

我们计划使用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个回答

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')
    };
}

根据您想要跟踪的方面,您可能需要添加更多的集合(例如为用户中心跟踪添加一个集合)。希望这可以帮助到您。

另请参阅

关于分析数据的博客文章


有趣的是,如果我想要显示过去一天内每小时“Hello”的浏览次数,那么find()语法会是什么样子呢? - Tom
那么,这个解决方案可能并不完美。但是稍等,我会发布更新。 - Matt
与此同时,您可能想看一下http://cookbook.mongodb.org/patterns/unique_items_map_reduce/。 - Matt
1
在我闭嘴之前,还有一件事:MongoDB将为您提供速度和灵活性,以尝试不同的方法。不要想太多,放手去做,看看它是否符合您的需求,如果不符合就改变它 :) - Matt
在复合索引上查询时要非常小心(这里需要)。如果索引的第一个键存在于查询中,则查询优化器可能会选择该索引。如果第一个键不在查询中,则只有在明确提示的情况下才会使用该索引。虽然索引可以在许多情况下用于查询字段的任意子集,但通常情况下,对于给定的查询,最佳索引是那些查询字段在任何未查询字段之前的索引。http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes - Lucas Zamboulis

1

我不会太担心空间问题,Mongo在这方面可以无限扩展,增加更多的空间成本也相对较低。

需要注意的一点是,如果您不断更新一个文档,它的大小将会增长,这意味着Mongo最终需要在索引中找到一个新的位置。如果您有很多正在更新并且增加大小的文档,Mongo将需要频繁地复制这些文档,这可能会显著减慢速度。当然,这完全取决于您预期的流量有多大。

根据我的经验,选择一个简单的文档格式,您不需要更新文档,这可能会使查询稍微复杂一些,但是您可以使用map/reduce获取所需的任何信息,而不管您的文档结构如何(map reduce非常灵活,只要有足够的经验,您可以做任何事情)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接