我正在尝试将全文搜索添加到系统中。我想写的查询需要涉及多次查找,然后搜索(如果可能的话)。
我有一张老师的桌子和一张主题表。
teacherProfile
teacherId [int] - primary key
subjectOneId [int]
subjectTwoId [int]
subjectThreeId [int]
teacherBiography [text]
subjects
subjectId [int]
subjectName [text]
所以最终我想要一个结果集......
teacherId [int]
teacherBiography [text]
( subjectOneName [text] )
( subjectTwoName [text] )
( subjectThreeName [text] )
所以括号中的最后三个字段是不存在的,但我确实想对它们进行文本搜索,我是否需要设置一个外键约束(如果对其进一步影响,我宁愿不这样做)现有系统)或者我能做些什么更有说服力的事情?
答案 0 :(得分:2)
MySQL
无法为视图编制索引,因此MySQL
无法实现您想要的内容。
您可以使用像Sphinx这样的外部全文索引引擎,并使用JOINS
或者,您可以创建非规范化表:
CREATE TABLE ftsearch
(
teacherId INT PRIMARY KEY,
teacherBiography TEXT,
subject1 TEXT,
subject2 TEXT,
subject3 TEXT,
)
ENGINE=MyISAM
并填写此查询:
INSERT
INTO ftsearch
SELECT teacherId, teacherBiography,
s1.name, s2.name, s3.name
FROM teacherProfile
LEFT JOIN
subject s1
ON s1.id = subjectOneId
LEFT JOIN
subject s2
ON s2.id = subjectTwoId
LEFT JOIN
subject s3
ON s3.id = subjectThreeId
及时。
实际上,如果您的所有表格都是MyISAM
,则可以将全文搜索查询(以布尔模式)应用于联接,而无需创建全文索引。
比如说,如果您要搜索'+Jones +math +physics'
,其中Jones
是教师的姓氏,math
和physics
是主题,则可以执行以下查询:
SELECT teacherId, teacherBiography,
s1.name, s2.name, s3.name
FROM teacherProfile
LEFT JOIN
subject s1
ON s1.id = subjectOneId
LEFT JOIN
subject s2
ON s2.id = subjectTwoId
LEFT JOIN
subject s3
ON s3.id = subjectThreeId
WHERE MATCH(teacherBiography) AGAINST ('+Jones' IN BOOLEAN MODE)
AND MATCH(t.teacherBiography, s1.name, s2.name, s3.name) AGAINST ('+Jones +math +physics' IN BOOLEAN MODE)
MATCH(teacherBiography) AGAINST ('+Jones')
会在FULLTEXT
上使用teacher
索引(如果有的话);第二个MATCH
将对结果进行精细过滤。
但是,涉及OR
条件或相关性排序的查询更复杂。