2012-08-28 107 views
1

背景:我有帖子和用户,都是HABTM社区。在我的岗位模型中,我有一个比较多少社区计算后的相关性给定用户的方法,他们的共同点是这样的:虚拟属性Mongoid查询数据库

def relevance(user) 
    (self.communities & user.communities).length 
end 

目的:要查询的帖子或者通过给定的相关性,即

Post.where(:relevance => 3) 

查询所有帖子,并通过相关性,即

Post.all.desc(:relevance) 
对它们进行排序

我知道用户变量需要在那里,只是想知道这样的事情是否可能或者是否存在解决方法。

+0

我担心你无法直接做到这一点。但是你可以使用一些map/reduce处理。 – apneadiving

+0

你可以扩大一点我不确定你想要完成什么。相关性在哪里计算?它是否已经存在于文档中? – Sammaye

+0

相关性是作为post.rb中的一种方法计算的(参见上面的代码),因为它对每个用户都不相同,必须在运行中进行计算。 – neon

回答

0

您可以使用Aggregation Framework(版本2.2中的新功能)在mongoDB中执行此操作。

你必须有用户社区的数组可用。在这个例子中,我将它称为userComms - 我期待它是一个与posts.communities具有相同类型值的数组。

db.posts.aggregate([ 
    { 
     "$unwind" : "$communities" 
    }, 
    { 
     "$match" : { 
      "communities" : { 
       "$in" : userComms 
      } 
     } 
    }, 
    { 
     "$group" : { 
      "_id" : "$_id", 
      "relevance" : { 
       "$sum" : 1 
      } 
     } 
    }, 
    { 
     "$sort" : { 
      "relevance" : -1 
     } 
    } 
]); 

这将返回形式的文件:

{ 
    "result" : [ 
     { 
      "_id" : 1, 
      "relevance" : 4 
     }, 
     { 
      "_id" : 6, 
      "relevance" : 3 
     }, 
... 
     ] 
} 

结果数组包含帖子的_ids和有关通过加入它们的共同点与用户社区的数目而计算。然后它按这个总和排序(降序)。

+0

刚开始使用Mongo时,我一直在寻找如何使用Mongoid来实现这个功能 - 虽然我不确定它是否可能。任何建议重新:这样做瓦特/ Mongoid? – neon

+0

您可以使用db.runCommand({aggregate:“collectionname”,pipeline:[...]})来执行任何聚合框架管道 –

+0

谢谢,我使用这种方法遇到的问题是帖子的相关性与每个用户。这意味着它需要current_user对象才能进行计算。有关如何做到这一点的任何想法? – neon