我在音乐库应用程序中使用的MySQL数据库中有三个表:
Genre
表包含列:
id
title
(字符串) Album
表包含列:
id
genre_id
(Genre.id
的外键)title
(字符串)artist
(字符串)并且Track
表包含列:
id
album_id
(Album.id
的外键)title
(字符串)每个Album
可以包含任意数量的Tracks
,每个Track
只有一个Album
,每个Album
只有一个Genre
。< / p>
我想实现一个关键字搜索,允许用户输入任意数量的关键字并找到所有Tracks
:
title
,Album
,匹配title
或artist
,Album
,Genre
与title
匹配。结果应按相关性排序。如果每个领域都有相关性排名,那就太好了。例如,title
的{{1}}可能比Track
的{{1}}更重要。
此外,解决方案应使用某种形式的部分搜索。搜索title
应首先将所有Genre
与rubber
Tracks
匹配,然后将title
与Rubber
匹配{{1}匹配}(Tracks
=通配符),然后转到title
,依此类推。但是,我并没有这么详细说明。我只是在寻找一个更通用的解决方案,我可以调整以满足我的特定需求。
我还应该提一下,我正在使用LAMP堆栈,Linux,Apache,MySQL和PHP。
实施此关键字搜索的最佳方式是什么?
更新: 我一直在尝试通过全文搜索来实现这一点,并提出了以下SQL语句。
*rubber*
答案 0 :(得分:4)
我会使用Apache Solr。使用Data Import Handler定义将所有表连接在一起的SQL查询,根据连接数据的结果创建全文索引。
名为args to MATCH()的列必须是您为索引定义的列,其顺序与您在索引中定义的顺序相同。但是你不能在MySQL中的多个表中定义任何索引(全文或其他)。
所以你不能这样做:
WHERE MATCH (g.title, a.title, a.artist, t.title) AGAINST ('beatles')
无论您使用的是布尔模式还是自然语言模式,都无关紧要。
你需要这样做:
WHERE MATCH (g.title) AGAINST ('beatles')
OR MATCH (a.title, a.artist) AGAINST ('beatles')
OR MATCH (t.title) AGAINST ('beatles')
您可能也对我的演示Practical Full-Text Search in MySQL感兴趣。
答案 1 :(得分:1)
在您要搜索的四列上定义全文索引,然后执行:
SELECT * FROM genre AS g
LEFT JOIN album AS a ON g.id = a.genre_id
LEFT JOIN tracks AS t ON a.id = t.album_id
WHERE MATCH (g.title, a.title, a.artist, t.title) AGAINST ('searchstring');
重新排序将按相关性排序。 有关全文搜索的更多详细信息,请参见此处: http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html
答案 2 :(得分:0)
我会使用像Sphinx这样的东西,你可以从你的查询中创建一个索引然后查询它。 有点难以理解,但结果比mysql AGAINST好10倍,以后你就不会有速度问题了。