我正在AppFog上运行博客风格的Web应用程序(来自Nodester)。 它是用NodeJS + Express编写的,并使用Mongoose框架持久化到MongoDB。
MongoDB是1.8版本,我不知道AppFog是否会将其升级到2.2。
为什么这个介绍?好吧,现在我的“帖子”显示在一个基本的“分页”可视化中,我的意思是它们只是从mongo中获取,按日期降序排序,一次一页。这是一个片段:
Post
.find({pubblicato:true})
.populate("commenti")
.sort("-dataInserimento")
.skip(offset)
.limit(archivePageSize)
.exec(function(err,docs) {
var result = {};
result.postsArray = (!err) ? docs : [];
result.currentPage = currentPage;
result.pages = howManyPages;
cb(null, result);
});
现在,我的目标是GROUP BY'dataInserimento'并显示像“日记”这样的帖子,我的意思是:
第1页=> 2012/10/08:我发布了3个帖子
第2页=> 2012/10/10:我展示了2个帖子(2012/10/09没有帖子,所以我不允许白页)
第3页=> 2012/10/11:35个帖子等......
我的想法是首先获得所有日期的分组列表(并且可能计算每天的帖子),然后构建页面链接,当访问页面(日期)时,查询如上,添加日期作为参数。
解:
聚合框架对此非常完美,但我无法掌握那个版本的Mongo,现在
以某种方式使用.group(),但它在分片环境中不起作用的想法并不让我兴奋! : - (
写一个MAP-REDUCE!我认为这是正确的方法,但我无法想象应该如何编写map()和reduce()。
请帮我一个小例子吗?
由于
编辑 :
peshkira的答案是正确的,然而,我不知道我是否真的需要。
我的意思是,我会有/ archive / 2012/10/01,/ archive / 2012/09/20等网址。
在每个页面中,足以获得查询帖子的日期。但是我必须显示“NEXT”或“PREV”链接,所以我需要知道包含帖子的下一天或前一天是什么,如果有的话。也许我可以只查询日期大于或小于当前日期的帖子,并获得第一个日期?
答案 0 :(得分:1)
假设你有类似的东西:
{
"author" : "john doe",
"title" : "Post 1",
"article" : "test",
"created" : ISODate("2012-02-17T00:00:00Z")
}
{
"author" : "john doe",
"title" : "Post 2",
"article" : "foo",
"created" : ISODate("2012-02-17T00:00:00Z")
}
{
"author" : "john doe",
"title" : "Post 3",
"article" : "bar",
"created" : ISODate("2012-02-18T00:00:00Z")
}
{
"author" : "john doe",
"title" : "Post 4",
"article" : "foo bar",
"created" : ISODate("2012-02-20T00:00:00Z")
}
{
"author" : "john doe",
"title" : "Post 5",
"article" : "lol cat",
"created" : ISODate("2012-02-20T00:00:00Z")
}
然后您可以使用map reduce,如下所示:
<强>地图
它只是将日期作为键和帖子标题发出。您可以将标题更改为_id,这可能对您更有用。如果您存储日期的时间,您只想使用日期(没有时间)作为键,否则mongo将按日期时间而不仅是日期进行分组。在我的测试用例中,所有帖子的时间都是00:00:00,所以没关系。
function map() {
emit(this.created, this.title);
}
<强>减少强>
它只执行任何操作,然后将键的所有值都推送到数组,然后将数组包装在结果对象中,因为mongo不允许数组是reduce函数的结果。
function reduce(key, values) {
var array = [];
var res = {posts:array};
values.forEach(function (v) {res.posts.push(v);});
return res;
}
<强>执行强>
使用db.runCommand({mapreduce: "posts", map: map, reduce: reduce, out: {inline: 1}})
将输出以下结果:
{
"results" : [
{
"_id" : ISODate("2012-02-17T00:00:00Z"),
"value" : {
"posts" : [
"Post 2",
"Post 1"
]
}
},
{
"_id" : ISODate("2012-02-18T00:00:00Z"),
"value" : "Post 3"
},
{
"_id" : ISODate("2012-02-20T00:00:00Z"),
"value" : {
"posts" : [
"Post 5",
"Post 4"
]
}
}
],
...
}
我希望这会有所帮助