【问题标题】:Mongoid Query DB by Virtual Attribute虚拟属性查询数据库
【发布时间】:2012-08-28 17:58:43
【问题描述】:

背景:我有帖子和用户,两者都是 HABTM 社区。在我的帖子模型中,我有一种方法可以通过比较他们有多少共同社区来计算帖子与给定用户的相关性:

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

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

Post.where(:relevance => 3)

查询所有帖子并按相关性排序

Post.all.desc(:relevance)

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

【问题讨论】:

  • 我担心你不能直接这样做。但是你可以使用一些 map/reduce 处理。
  • 你能扩大一点吗?我不确定你想要完成什么。相关性在哪里计算,是否已经存在于文档中?
  • 相关性是作为 post.rb 中的一种方法计算的(参见上面的代码),因为每个用户的相关性都不同,并且必须即时计算。
  • 啊,好的,所以您滚动浏览分配此功能的每个帖子,现在您想按该功能对下摆进行排序。我相信 MongoDB 在其驱动程序中本身并不支持此功能,因此您可能需要找到一个可以为您执行此操作的函数,可能是 ruby​​ 中的快速排序函数。我个人不知道,因为我不是 ruby​​ 程序员。

标签: ruby-on-rails ruby-on-rails-3 mongodb mongoid mongoid3


【解决方案1】:

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

您必须拥有一系列可用的用户社区。在本例中,我将其称为 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 和相关性,通过添加他们与用户共同拥有的社区数量计算得出。然后按该总和排序(降序)。

【讨论】:

  • 刚开始使用 Mongo,我一直在寻找如何使用 Mongoid 来实现它——尽管我不确定它是否可能。有什么建议:用 Mongoid 做这个?
  • 您可以使用 db.runCommand({aggregate:"collectionname",pipeline:[...]}) 执行任何聚合框架管道
  • 谢谢,我在使用这种方法时遇到的问题是每个用户的帖子相关性都不同。这意味着它需要 current_user 对象才能被计算。关于如何做到这一点的任何想法?
  • 这就是“userComms”在我的示例中所代表的含义。您将用户的社区读入一个数组并将其用作此查询的参数,并且响应将是有效的仅针对此用户并且仅“现在”。
猜你喜欢
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多