首先,这是我第一次来蒙戈.
概念:
>用户可以用自然语言描述图像.
>划分用户输入并将他描述的词存储在名为
话.
>用户必须能够浏览最常用的单词并将这些单词添加到其描述中.
>系统将使用最常用的词(适用于所有用户)并使用
这些词来形容图像.
{
"date": "date it was inserted"
"reported": 0,
"image_id": "image id"
"image_name": "image name"
"user": "user _id"
"word": "awesome"
}
这些单词将被复制,以便每个单词都可以与用户相关联…
问题:我需要执行Mongo查询,以使我知道不是给定用户创建的最常用的单词(用于描述图像). (达到上述第3点)
我已经看过MapReduce算法,但是根据我的阅读,它有两个问题:
>无法对结果进行排序(我可以从最常用到最不常用的顺序排序)
>在数百万个文档中,它可能需要大量的处理时间.
>无法限制返回的结果数
我考虑过每天在给定时间运行一项任务,以将给定用户不曾用来描述给定图像的单词等级存储在文档中(在另一个集合中).我必须将其限制为300个结果或类似的东西(在适当的限制范围内的任何想法?),例如:
{
user_id: "the user id"
[
{word: test, count: 1000},
{word: test2, count: 980},
{word: etc, count: 300}
]
}
我看到的这种解决方案的问题是:
>结果会有相当长的延迟,这是不希望的.
>在为所有用户生成此文档时服务器负载可能会激增(我实际上在Mongo中对此知之甚少,所以这只是一个假设)
也许我的方法没有任何意义……也许我在Mongo中缺乏经验使我指向了错误的“模式设计”.
有什么想法可以解决这种问题?
不好意思,谢谢您的宝贵时间和帮助!
若昂
解决方法:
如前所述,您可以使用易于使用的group命令,但是您需要在客户端对结果进行排序.同样,结果作为单个BSON对象返回,因此必须非常小-少于10,000个密钥,否则您将获得异常.
基于您的数据结构的代码示例:
db.words.group({
key : {"word" : true},
initial: {count : 0},
reduce: function(obj, prev) { prev.count++},
cond: {"user" :{ $ne : "USERNAME_TO_IGnorE"}}
})
另一种选择是使用新的Aggregation framework,它将在2.2版本中发布.这样的事情应该起作用.
db.words.aggregate({
$match : { "user" : { "$ne" : "USERNAME_TO_IGnorE"} },
$group : {
_id : "$word",
count: { $sum : 1}
}
})
或者,您仍然可以使用MapReduce.实际上,您可以对输出进行限制和排序,因为结果是
一个集合.只需在输出上使用.sort()和.limit()即可.您也可以使用增量
map-reduce输出选项,它将帮助您解决性能问题.看一下MapReduce中的out参数.
下面是一个示例,该示例使用增量功能将现有集合与words_usage集合中的新数据合并:
m = function() {
emit(this.word, {count: 1});
};
r = function( key , values ){
var sum = 0;
values.forEach(function(doc) {
sum += doc.count;
});
return {count: sum};
};
db.runcommand({
mapreduce : "words",
map : m,
reduce : r,
out : { reduce: "words_usage"},
query : <query filter object>
})
# retrieve the top 10 words
db.words_usage.find().sort({"value.count" : -1}).sort({"value.count" : -1}).limit(10)
我猜您可以每隔几分钟/小时在cron中运行上述MapReduce命令,这取决于您想要的结果的准确性.对于更新查询条件,可以使用文档创建日期一词.
拥有系统热门单词集合后,您可以为每个用户构建热门单词或仅实时计算它们(取决于系统大小).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。