【问题标题】:Designing "relevance-based" search?设计“基于相关性”的搜索?
【发布时间】:2011-08-18 04:30:51
【问题描述】:

在我的应用程序 (PHP/MySQL/JS) 中,我内置了一个搜索功能。其中一个搜索条件包含各种选项的复选框,因此,如果某些结果包含更多内容,它们会比其他结果更相关每个选项或更少。

即选项是 A 和 B,如果我同时搜索选项 A 和 B,结果 1 仅包含选项 A 的相关性为 50%,而同时包含选项 A 和 B 的结果 2 相关性为 100%。

之前,我只是根据表单输入进行简单的 SQL 查询,但这有点困难,因为它不像数据 LIKE "%query%" 那样简单,而是某些结果对某些人更有价值搜索查询,有些不是。

我完全不知道从哪里开始......有人有相关的(哈!)阅读材料可以指导我吗?

编辑:经过深思熟虑后,我正在考虑使用 SQL 脚本来获取原始数据,然后进行多轮解析是我必须要做的事情......

但是没有可缓存的东西? :(

【问题讨论】:

  • 选项 A 和 B 如何存储在您的表中?
  • 在一个表中,根据选项为 1 或 0。但这最终会被混入其他搜索条件中......
  • 添加了答案,请务必查看并评论问题。
  • 忘了说我的方法是可缓存的。

标签: php javascript mysql search relevance


【解决方案1】:

看看 lucence 项目 它有多种语言版本

这是 php 端口 http://framework.zend.com/manual/en/zend.search.lucene.html

它对要搜索的项目进行索引并返回相关的加权搜索结果,例如,最好从 y 中选择 x,其中名称类似于 '%pattern%' 样式搜索

【讨论】:

  • @julian,我只是认为您可以从他们使用的加权过程中发现一些东西,因为这本质上就是您想要做的。加权您的结果,以便最相关的结果出现在顶部
【解决方案2】:

您需要一个强大的搜索引擎,例如 solr。虽然您可以在 mysql 之上实现这一点,但它已经与其他工具一起提供了开箱即用的功能。

【讨论】:

    【解决方案3】:

    这是一个想法:进行比较并对结果求和。总和越高,匹配的条件越多。

    这样的(愚蠢的)桌子怎么样:

    • 姓名
    • dob_year
    • dob_month
    • dob_day

    找出与 1980 年 3 月 15 日最相似的三个日期组成部分的人:

    SELECT (dob_year = 1980) + (dob_month = 3) + (dob_day = 15) as strength, name
    from user
    order by strength desc
    limit 1
    

    需要一个好的 WHERE 子句和索引来阻止您进行表扫描,但是...

    您甚至可以为列添加权重,例如

    SELECT ((dob_year = 1980)*2)
    

    祝你好运。

    【讨论】:

      【解决方案4】:

      鉴于您对我的评论的回答,这里有一个示例,说明您可以如何做到这一点:

      首先是表格:

      CREATE TABLE `items` (
       `id` int(11) NOT NULL,
       `name` varchar(80) NOT NULL
      );
      CREATE TABLE `criteria` (
       `cid` int(11) NOT NULL,
       `option` varchar(80) NOT NULL,
       `value` int(1) NOT NULL
      );
      

      然后是一些项目和标准的示例:

      INSERT INTO items (id, name) VALUES
      (1,'Name1'),
      (2,'Name2'),
      (3,'Name3');
      
      INSERT INTO criteria VALUES
      (1,'option1',1) ,(1,'option2',1) ,(1,'option3',0),
      (2,'option1',0) ,(2,'option2',1) ,(2,'option3',1),
      (3,'option1',1) ,(3,'option2',0) ,(3,'option3',1);
      

      这将创建 3 个项目和 3 个选项,并为它们分配选项。

      现在您可以通过多种方式按一定的“强度”进行排序。其中最简单的是:

      SELECT i . * , c1.value + c3.value AS strength
      FROM items i
      JOIN criteria c1 ON c1.cid = i.id AND c1.option = 'option1'
      JOIN criteria c3 ON c3.cid = i.id AND c3.option = 'option3'
      ORDER BY strength DESC 
      

      这将显示所有具有选项 1 或选项 3 的项目,但同时具有这两个选项的项目似乎排名“更高。

      如果您要搜索 2 个选项,这很有效。但是让我们假设您搜索所有 3 个选项。现在所有项目都具有相同的强度,这就是为什么为选项分配“权重”很重要。

      您可以将值作为您的优势,但如果您的查询并不总是为所有地方的相同选项分配相同的权重,这可能对您没有帮助。这可以通过以下查询在每个查询的基础上轻松实现:

      SELECT i.* , IF(c1.value, 2, 0) + IF(c3.value, 1, 0) AS strength
      FROM items i
      JOIN criteria c1 ON c1.cid = i.id AND c1.option = 'option1'
      JOIN criteria c3 ON c3.cid = i.id AND c3.option = 'option3'
      ORDER BY strength DESC
      

      尝试查询,看看是否是您需要的。

      我还想指出,就处理能力而言,这并不是最佳解决方案。我建议您添加索引,使选项字段为整数,尽可能缓存结果。

      如果您有任何问题或要添加的内容,请发表评论。

      【讨论】:

        猜你喜欢
        • 2013-10-04
        • 1970-01-01
        • 1970-01-01
        • 2014-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多