跨多个相关表的相关性搜索

时间:2012-03-31 07:23:04

标签: mysql search full-text-search relevance

我有一个名为cards的表,其中包含相关表brigadesidentifiers。单张卡可以有多个旅和标识符。我想进行一次搜索,例如'purple king',其中'purple'是一个旅,'king'是一个标识符,并查找带有这些旅和标识符的卡片。对类似问题https://stackoverflow.com/a/9951200/633513的回答显示了如何跨多个表格进行全文搜索。我想做同样的事情,除了我只想要相关的比赛。这可能吗?

表结构:

Cards: id as INT, title as VARCHAR(50)
Brigades: id as INT, brigade as VARCHAR(50)
Identifier: id as INT, identifier as VARCHAR(50)

加入表:

CardBrigades: id as INT, card_id as INT, brigade_id as INT
CardIdentifiers: id as INT, card_id as INT, identifier_id as INT

示例标识符:

Angel
Animal
Archer
Army
Assyrian
Babylonian
Based on Prophecy
Beast
Bows, Arrows, Spears, Javelins and Darts
Canaanite
'Capture' in Special Ability
'Censer' in Title
Chief Priest
Child of Leah
Commander
Connected to David
Connected to Demons
'Covenant' in Title
'David' in Title
'David' in Verse
Deacon
Prince

样本旅:

None
Black
Brown
Crimson
Gold (Evil)
Gray
Orange
Pale Green
Multi (Evil)
Blue
Gold (Good)
Green
Purple
Red
Silver
Teal
White
Multi (Good)
Multi

2 个答案:

答案 0 :(得分:1)

根据您发布的链接中的答案,您可以执行类似的操作

SELECT id,SUM(relevance) as total_relevance FROM (
SELECT 
    id, 
    (MATCH(title) AGAINST ('search string')) AS relevance
    FROM Cards
UNION
SELECT 
    Cards.id,
    (MATCH(brigade) AGAINST ('search string')) AS relevance
    FROM Brigades 
    INNER JOIN CardBrigades ON Brigades.id=brigade_id
    INNER JOIN Cards ON card_id=Cards.id 
UNION
SELECT 
    Cards.id,
    (MATCH(identifier) AGAINST ('search string')) AS relevance
    FROM Identifier 
    INNER JOIN CardIdentifier ON Identifier.id=identifier_id
    INNER JOIN Cards on card_id=Cards.id 
) AS combined_search 
GROUP BY id
HAVING total_relevance > 0

我不确定这会有多好。你可能最好不要再看另一个解决方案,比如Solr,Lucene甚至NoSQL存储引擎。

答案 1 :(得分:0)

如果你只想要相关的(相关?)结果,你可以在BOOLEAN模式中使用FULLTEXT搜索,如下所示:

select 
    identifier, brigade, P.id as identifier_id, B.id as brigade_id, 
    match(identifier)  against ('purple prince') +
    match(brigade)     against ('purple prince')   as score
from Identifier P, Brigade B
where 
    match(identifier)  against ('purple prince' IN BOOLEAN MODE) and 
    match(brigade)     against ('purple prince' IN BOOLEAN MODE)
order by -score
;

(为了简单起见,我只显示查询的FULLTEXT搜索部分,并省略了与Card *表的连接)