我需要使用MySQL制作同义词搜索功能。
这是表结构:
NAMES_TABLE SYNONYMS_TABLE
------------ --------------
ID | NAME ID_1 | ID_2
---+-------- ------+-------
1 | NAME_A 1 | 2
2 | NAME_B 2 | 1
3 | NAME_C 1 | 3
4 | NAME_D 3 | 1
5 | NAME_E 4 | 5
5 | 4
我希望它能像这样工作:输入一个单词,在表格中发送给我所有相应的单词,其中索引在同义词表中,如ID_1或ID_2。
但我无法提出要求......
感谢您的帮助。
答案 0 :(得分:1)
一个方向:ID_1是名称,ID_2是同义词:
select
sn.NAME
from
NAMES_TABLE n
inner join SYNONYMS_TABLE s on s.ID_1 = n.ID
inner join NAMES_TABLE sn on sn.ID2 = s.ID_2
where
n.NAME = :NAME
双向:ID_1或ID_2可以包含名称,而另一个是同义词。
select
sn1.NAME
from
NAMES_TABLE n1
inner join SYNONYMS_TABLE s1 on s1.ID_1 = n1.ID
inner join NAMES_TABLE sn1 on sn1.ID = s1.ID_2
where
n1.NAME = :NAME
union
select
sn2.NAME
from
NAMES_TABLE n2
inner join SYNONYMS_TABLE s2 on s2.ID_2 = n2.ID
inner join NAMES_TABLE sn2 on sn2.ID = s2.ID_1
where
n2.NAME = :NAME
注意在第二个查询的第二部分中反转ID_2和ID_1。
您需要哪一种,取决于数据。如果你想让'lane'成为'road'的同义词,而不是相反,你应该使用第一种方法。但在这种情况下,你必须记住两个方向的同义词应该加两次,所以你会得到:
NAMES_TABLE SYNONYMS_TABLE
------------ --------------
ID | NAME ID_1 | ID_2
---+-------- ------+-------
1 | Road 1 | 3
2 | Lane 3 | 1
3 | Street 2 | 1
现在道路和街道都是对方的同义词,但是虽然Lane是Road的同义词,但Road并不适合Lane。
如果你不想要这种行为,你最好使用第二种,尽管你可能会冒险通过交换ID_1和ID_2来输入双重记录。您应该能够通过检查ID_2始终高于ID_1,从不相同或更低来阻止这种情况。
答案 1 :(得分:1)
接近此JOIN的东西应该可以正常工作。
SELECT n1.NAME
FROM NAMES_TABLE n1
JOIN SYNONYMS_TABLE s1
ON s1.ID_1 = n1.ID
JOIN NAMES_TABLE n2
ON s1.ID_2 = n2.ID
WHERE n2.NAME = ?
由于您要检查两个名称行(原始和同义词),您需要通过SYNONYMS_TABLE将表NAMES_TABLE与其自身连接。