我使用mongodb作为我的博客平台,用户可以在其中创建自己的博客。所有博客中的所有条目均位于条目集合中。一个条目的文档如下所示:Mongodb:选择每个组的前N行
{
'blog_id':xxx,
'timestamp':xxx,
'title':xxx,
'content':xxx
}
正如问题所述,是否有任何方法可以为每个博客选择最后3个条目?
我使用mongodb作为我的博客平台,用户可以在其中创建自己的博客。所有博客中的所有条目均位于条目集合中。一个条目的文档如下所示:Mongodb:选择每个组的前N行
{
'blog_id':xxx,
'timestamp':xxx,
'title':xxx,
'content':xxx
}
正如问题所述,是否有任何方法可以为每个博客选择最后3个条目?
做到这一点基本蒙戈如果你可以用两件事情唯一可行的生活方式:
如果是这样,这里是你如何做到这一点:
在创建一个NE w介绍是否正常插入,然后执行此更新以增加所有帖子的时间(包括刚刚为此博客插入的帖子):
db.entries.update({blog_id:BLOG_ID},{age:{ $ INC:1}},假,真)
查询时,请使用以下查询将返回最近的3项为每个博客:
db.entries.find({年龄:{$ LTE:3},时间戳:{$ GTE:STARTOFMONTH,$ LT:ENDOFMONTH}})排序({blog_id:1,年龄:1})
请注意,此解决方案实际上是并发安全的(没有重复年龄的条目)。
它可能与组(聚合),但这将创建一个全表扫描。
你确实需要3个或者你能设置一个限制吗......例如:最多3个帖子/上个星期/月?
理想我想精确地选择3,但是从上个月最多3个职位可够好,如果我不能找到除了数据非规范化的解决方案。你能举个例子说明如何做到这一点吗?从所有mongodb的地图缩小教程我已阅读他们只显示如何计算统计(聚合)... – Tacaza
这个答案使用的地图由drcosta减少从另一个问题的伎俩
In mongo, how do I use map reduce to get a group by ordered by most recent
mapper = function() {
emit(this.category, {top:[this.score]});
}
reducer = function (key, values) {
var scores = [];
values.forEach(
function (obj) {
obj.top.forEach(
function (score) {
scores[scores.length] = score;
});
});
scores.sort();
scores.reverse();
return {top:scores.slice(0, 3)};
}
function find_top_scores(categories) {
var query = [];
db.top_foos.find({_id:{$in:categories}}).forEach(
function (topscores) {
query[query.length] = {
category:topscores._id,
score:{$in:topscores.value.top}
};
});
return db.foo.find({$or:query});
您需要首先由blog_id
和timestamp
场集合中的文档进行排序,然后做一个初步按降序创建原始文档的数组。之后,您可以使用文档切片数组以返回前3个元素。
直觉可以遵循下面的例子:
db.entries.aggregate([
{ '$sort': { 'blog_id': 1, 'timestamp': -1 } },
{
'$group': {
'_id': '$blog_id',
'docs': { '$push': '$$ROOT' },
}
},
{
'$project': {
'top_three': {
'$slice': ['$docs', 3]
}
}
}
])
谢谢,辉煌 –
有你的想法。我没有想到这样的事情。创建新帖子时的额外更新不会成为问题。但是,当用户删除帖子时,我们必须更新所有其他帖子的“年龄”字段。只有删除的帖子“年龄”<= 3时,该更新才能被限制。我错过了什么? – Tacaza
是的,您不应该将更新限制为年龄<3,因为您最终会得到重复的年龄。就地更新非常快,所以它不应该是一个问题。删除意味着删除条目并将年龄减少1,其中age> deleted_post.age。祝你好运。 –
这绝对有道理。感谢您的建议! – Tacaza