2013-02-01 137 views
3

我在mongodb中有一个相当大的集合,大约有100 000个文档(未分片)。这是一个Web应用程序的后端,它基本上只允许用户浏览不同的方式来查看此集合中的相同信息。Mongodb聚合结果缓存

对于我试着算使用聚合框架领域出现的次数的意见之一。这意味着汇总整个集合。问题是这个聚集操作(这是一个简单的组管道,排序和限制)需要2秒,这对于Web应用程序来说太慢了。

所以我的问题是,为了缓存聚合操作的结果,首选解决方案是什么?据我所知,不可能“聚合”成一个新的集合,或类似的东西。目前我唯一找到的解决方案是将整个结果读入一个变量,然后使用insert将这个变量插入到一个新的集合中 - 但是我担心这会涉及从数据库发送大量数据=>到我的应用程序=>回到数据库?

有什么建议吗?管道

例子:

res = items.aggregate([ 
    { "$group": { "_id": { "item_id": "$item_id", "title": "$title", "category": "$category" }, "count": { "$sum": 1 } } }, 
    { "$sort": { "count": -1 } }, 
    { "$limit": 5 } 
]) 

架构基本上是这3场+几个是真的不相关,即:

doc = { 
    "item_id": 1000, 
    "title": "this is the item title", 
    "category": "this is the item category" 
} 

我已经试过两个ITEM_ID和所有指数3个领域没有成功。

+1

如果您可以提供您的文档的示例结构和聚合管道的步骤,这可能会很有用。你使用索引? – attish

回答

1

聚集返回结果到一个文档。结果受限于16M。该文件返回到应用程序。

如果你想“聚合”到一个集合 - 使用map-reduce。

map_function = function() { 
     emit(this.item_id, {"item_id": this.item_id, /* any other info */ "count": 1}); 
}; 

reduce_function = function (key, values) { 
     var result = {"item_id": key, /* any other info should be given from one or any of values array objects */ "count": 0}; 
     values.forEach(function (value) { 
       result["count"] += value["count"]; 
     }); 
     return result; 
}; 

不确定您是否可以发出结构性值 - 请尝试。 BTW发射的关键字段是好的。

+0

那么如何使用map-reduce解决这个问题呢? – agnsaft

+0

已添加到答复。 –