代码之家  ›  专栏  ›  技术社区  ›  warren

如何:排名搜索结果

  •  9
  • warren  · 技术社区  · 16 年前

    我有一个webapp开发问题,我已经为它开发了一个解决方案,但是我正在尝试寻找其他的方法来解决我看到的一些性能问题。

    问题陈述:

    • 用户输入几个关键字/令牌
    • 应用程序搜索与令牌匹配的项
    • 每个令牌需要一个结果
      • 如果一个条目有3个令牌,我需要条目ID 3次
    • 对结果进行排名
      • 为令牌匹配分配X点
      • 根据点对条目ID进行排序
      • 如果点值相同,则使用日期对结果进行排序

    我想做的是发送一个查询,该查询返回类似于in()的结果,但返回的每个标记的重复条目ID与选中的每个条目ID匹配。

    有没有比我现在做的更好的方法,使用多个单独的查询,每个令牌运行一个查询?如果是这样,最简单的实现方法是什么?

    编辑
    我已经对条目进行了标记,例如,“see spot run”的条目ID为1,而三个标记“see”、“spot”、“run”则位于单独的标记表中,条目ID与它们相关,因此该表可能如下所示:

    'see', 1 
    'spot', 1 
    'run', 1 
    'run', 2 
    'spot', 3 
    
    4 回复  |  直到 15 年前
        1
  •  6
  •   warren    15 年前

    您可以在一个查询中使用mysql中的“union all”来实现这一点。

    只需循环访问php中的令牌,为每个令牌创建一个union all:

    例如,如果标记是“x”、“y”和“z”,则查询可能如下所示

    SELECT * FROM `entries` 
    WHERE token like "%x%" union all 
        SELECT * FROM `entries` 
        WHERE token like "%y%" union all 
            SELECT * FROM `entries` 
            WHERE token like "%z%" ORDER BY score ect...
    

    ORDER子句应该将整个结果集作为一个结果集进行操作,这正是您需要的。

    在性能方面,它不会那么快(我猜是这样),但是对于数据库,速度方面的主要开销通常是从PHP向数据库引擎发送查询并接收结果。使用这种技术,这种情况只发生一次而不是每个令牌一次,所以性能会提高,我只是不知道是否足够。

        2
  •  3
  •   David McLaughlin    16 年前

    我知道这不是你问的问题的严格答案 但是如果您的表是数千行而不是数百万行 ,那么全文解决方案可能是最好的方法。

    在MySQL中,当您在索引列上使用match时,您提供的每个关键字都将得到一个相关性得分(大致按每个关键字被提到的次数计算),这将比您的方法更准确,而且对于多个关键字肯定更有效。

    请参见这里: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

        3
  •  1
  •   Erik    16 年前

    如果您使用的是union all模式,那么您可能还希望在查询中包含以下部分:

    SELECT COUNT(*) AS C
    ...
    GROUP BY ID
    ORDER BY c DESC
    

    虽然这是一个非常简单的例子,但它确实为每个结果提供了匹配的频率,并且可以从一个伪秩开始。

        4
  •  0
  •   Matt Sheppard    16 年前

    如果使用为搜索任务而不是数据库设计的数据结构,您可能会获得更好的性能。例如,您可以尝试在 inverted index . 然而,你可能不想自己写,而是想看看 Lucene 大部分工作都是为你做的。