【问题标题】:user matching system, efficient search approach?用户匹配系统,高效搜索方式?
【发布时间】:2011-10-30 20:35:06
【问题描述】:

编辑:我知道已经一年多了,但我终于对这个问题有了新的认识。要查看此问题的更新,请查看此问题:Rails 3 user matching-algorithm to SQL Query (COMPLICATED)

我正在开发一个根据回答的问题匹配用户的网站。

例如,每次用户访问另一个用户的个人资料页面时,都会计算匹配百分比。所以匹配百分比不存入数据库,一直在重新计算。

现在我想构建一个搜索功能,用户可以在其中搜索最佳匹配。

我的问题是,最有效的方法是什么?

如果我有 50k 用户,我必须按匹配百分比对他们进行排序。我是否必须计算一个和其他 50k 用户之间的每个匹配百分比,然后从中创建一个列表?对我来说听起来有点低效。这不会大大降低应用程序的速度吗?

我希望有人能帮我解决这个问题,因为这让我有点头疼。

编辑: 为了澄清一点,这是我的用户、问题、答案、user_answers 和accepted_answers 的数据库模型:

    Tables:
    Users(:id, :username, etc.)
    Questions(:id, :text)
    Answers(:id, :question_id, :text)
    UserAnswers(:id, :user_id, :question_id, :answer_id, :importance)
    AcceptedAnswers(:id, :user_answer_id, :answer_id)

    Questions <-> Answers: one-to-many
    Questions <-> UserAnswers: one-to-many
    Users <-> UserAnswers: one-to-many
    UserAnswers <-> AcceptableAnswers: one-to-many

因此,有一个问题列表(包含此问题的可能答案),用户对这些问题给出“用户答案”,分配该问题对他们的重要性以及他们从其他用户那里接受的答案。

然后,如果您使用 User1 和 User2,则查找常见的已回答问题,因此 UserAnswers 的 question_id 相同。他们有 10 个共同的问题。用户 1 给前五个问题的重要性值 10,给其他五个问题的重要性值 20。用户 2 对两个 20 值问题和三个 10 值问题给出了可接受的答案。总分70分。最高可达到的分数当然是 20x5 + 10x5... 所以 User2 达到 70/150 * 100 = 46,66% ... 同样的事情是相反的,对于 User1 达到了 User2 分配给这些问题的分数的多少.然后通过几何平均值将这 2 个百分比组合起来:sqrt of percent1 * percent2 ... 这给出了最终匹配百分比

【问题讨论】:

  • 这是一个复杂的信息检索问题。每次计算匹配百分比可能永远不够快。准确检查您是如何计算匹配百分比的会有很大帮助。
  • 如果我是你,我会创建一个索引来存储每个用户与每个其他用户的百分比关系。创建一个单独的应用程序,每 5 分钟运行一次并重新创建此索引,然后在您的 rails 代码中只需简单地对列表进行排序并返回结果。我没有看到可以让您“即时”计算所有百分比的解决方案
  • 您的 rails 应用程序会更快。您排序 50,000 个百分比,而不是计算 50,000 个百分比。您只需要在内容更新后重新计算百分比。所以第一次是 25 亿,后来很少了。
  • 你有一个非常有趣的问题。我正在考虑解决方案并进一步感兴趣。据我所知,您不能将最终百分比存储在某个地方,因为当有新问题或答案出现时,您将无法直接更改百分比(涉及几何平均值)。您首先需要更改重要性的总和并从那里重新计算百分比。我有一些半生不熟的 sql,但远非可接受的解决方案。随时通知我们!
  • @Mexxer:提出了一个可能的解决方案,主要是在gist.github.com/1158234@ 的 db 中进行所有计算

标签: ruby-on-rails database database-design


【解决方案1】:

@Wassem 对您的问题的回答似乎很到位。我还建议您采取一种方法,根据新答案和新接受的答案更新百分比。

我创建了一个仅限数据库的解决方案 (gist),它可以工作,但具有中间表的额外复杂性。

理想情况下,您应该再创建两张表,一张用于重要性,另一张用于百分比匹配。当用户分配/更新答案的重要性或将某些答案标记为可接受时,您应该在这些表中创建/插入/删除行。您还可以利用delayed_job 或rescue 在后台更新特定操作的表。

您可能需要偶尔运行一次 sql 来同步两个新表中的数据,因为在某些情况下,由于并发以及更新操作的顺序可能会导致不一致。

对已接受答案的更新应该是直截了当的,因为您只需要更新一对。但是,如果有人对某个问题赋予了重要性,则可能需要进行大量计算,并且可能需要更新大量百分比。为避免这种情况,您可以选择仅维护具有每对重要性总和的表,在需要时对其进行更新并即时计算实际百分比(在 db 中)。

【讨论】:

  • 问题是,总是分配新的重要性。用户很少单独添加已接受的答案。他们通常会回答一个创建 UserAnswer 的问题,并创建许多 AcceptedAnswers。所以大多数时候会有很多计算。也许最好让它即时计算?我想我必须测试这两种选择,看看哪个表现最好。
【解决方案2】:

我建议您保留数据库中所有用户的匹配百分比。创建一个表matches,其中包含一对用户的匹配百分比。您不需要为数据库中的所有用户对保存匹配百分比。只有当他们中的任何一个接受了其他用户的回答时,才会为两个用户计算有效匹配百分比。大多数用户不会接受其他大多数用户的回答。

我建议您不要在用户访问其他用户个人资料时计算并保存匹配百分比。但是当一个用户接受另一个用户的答案时。这将确保您不会进行任何不必要的计算,并且一对用户的匹配百分比始终新鲜

【讨论】:

  • 嗯,不完全……系统首先查找常见的已回答问题……然后计算一个用户从另一个用户获得的重要性值的百分比。假设用户 1 和用户 2 有 10 个常见问题,用户 2 根据用户 1 接受的答案的设置,只对这 10 个问题给出了一个可接受的答案。 User1 对这些问题中的每一个都给出了 10 的值。这意味着 User2 与 User1 的匹配度达到了 10%。反过来做同样的事情。
  • 问题是......每个用户都可能以某种方式回答了其他用户也接受的问题。这仍然会为每个用户对计算匹配百分比
  • 我认为我的问题的第一个 cmets 仍然是最好的。将其拆分为 2 个应用程序...像您所说的那样有一个匹配表,让第二个应用程序进行所有计算...如果一个用户回答了一个新问题,那么系统会查找所有回答相同问题的用户并重新计算这些用户对的匹配百分比。
  • 我认为当用户发布新答案时,用户的匹配百分比会发生变化。
  • 是的,我仍然需要一种方法来处理那张巨大的桌子。因为它呈指数增长......如果我有 50k 用户(而 50k 并没有那么多),我已经有 25 亿个表行。
猜你喜欢
  • 2023-03-08
  • 2013-12-13
  • 2022-08-04
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多