【发布时间】:2015-03-15 13:30:14
【问题描述】:
我有一个包含音乐歌曲的 SQL 数据库。当然,每首歌都有一个艺术家、一张专辑和一个流派。他们还有一个通用的“人气”计数器,该计数器是从外部来源获得的。但是,我也想让用户有机会对歌曲进行投票。最后,搜索结果应该根据这个受欢迎程度以及结果与原始查询的准确性进行排序。
我目前使用的查询如下:
SELECT *
FROM p2pm_tracks
WHERE
`artist` LIKE '%$searchquestion%' OR
`genres` LIKE '%$searchquestion%' OR
`trackname` LIKE '%$searchquestion%' OR
`album_name` LIKE '%$searchquestion%'
ORDER BY `popularity` DESC
LIMIT $startingpoint, $resultsperpage
我在以下问题上苦苦挣扎:
- 用户搜索某些内容。我查看了所有领域:歌曲 title、artist、album 和 genre。但是,通常某个搜索查询包含多个(部分)这些轨道。
例如,用户可能会搜索Opening Philip Glass。
在这种情况下,第一个词是歌曲的名称,第二个和第三个词是艺术家的名字。
另一个例子:
如果我将查询拆分为空格,则会找到正确的曲目。但是,如果仅匹配其中一个词的另一条轨道具有更高的流行度,它将在实际准确匹配搜索查询的那条之前返回。
我仍然希望以一种方式对结果进行排序,即同时匹配查询的较大部分的内容位于顶部。我怎样才能使用 SQL 做到这一点?
- 我有静态流行度,想创建一个新的。因此,我想使用某个轨道上所有投票的平均值(这些投票存储在另一个表中),除非在还没有投票的情况下。 我如何构造一个执行此操作的 SQL 查询?
我的应用程序是用 PHP 构建的,但我想尽可能多地在 SQL 中执行此操作,最好使用尽可能少的查询以减少延迟。
任何帮助将不胜感激。
【问题讨论】:
-
SQL 不是完成此任务的最佳方式。文本搜索引擎(例如 Solr Lucene)是一种更好的方法,特别是如果您允许像
opening philip glass这样的搜索。一些 RDBMS(例如 SQL Server)确实内置了全文引擎,并且可能是合适的。 -
另请注意,您的 MySQL 查询现在很容易受到这种方式的 SQL 注入攻击。总是逃避你的查询。
-
您可以在服务器端使用 levenstein php.net/manual/en/function.levenshtein.php对其进行排序
-
我很想给你一个答案,但我需要先处理一些 sql 转储,如果你可以发给我,我想我可以帮助你。
-
@Ruben:别担心,我会在将语句插入查询之前对其进行清理。我确实从中学到了:xkcd.com/327
标签: php sql database search search-engine