문제

I'm trying to add a full text search to a system. The query I want to write needs to involve multiple lookups followed by the search (if that's even possible).

I've got a table of teachers and a table of subjects.

teacherProfile
teacherId [int] - primary key
subjectOneId [int]
subjectTwoId [int]
subjectThreeId [int]
teacherBiography [text]

subjects
subjectId [int]
subjectName [text]

So ultimately I want a resultset along the lines of..

teacherId [int]
teacherBiography [text]
( subjectOneName [text] )
( subjectTwoName [text] )
( subjectThreeName [text] )

So these last three fields in brackets are non existant but I do want to perform a text search upon them, do I need to setup a foriegn key constraint (which I'd rather not to do in case of further impacts on the existing system) or is there something more eloquent I can do?

도움이 되었습니까?

해결책

MySQL cannot index views so what you want is impossible in MySQL.

You can use an external fulltext indexing engine like Sphinx and load data there using a query with JOINS

Alternatively, you can create a denormalized table:

CREATE TABLE ftsearch
        (
        teacherId INT PRIMARY KEY,
        teacherBiography TEXT,
        subject1 TEXT,
        subject2 TEXT,
        subject3 TEXT,
        )
ENGINE=MyISAM

and fill it with this query:

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 

on a timely basis.

Actually, if all your tables are MyISAM, you can apply fulltext search queries (in boolean mode) to a join, without having to create a fulltext index.

Say, if you are searching for '+Jones +math +physics', where Jones is a teacher's surname and math and physics are subjects, you can do this query:

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)

The MATCH(teacherBiography) AGAINST ('+Jones') will use a FULLTEXT index on teacher, if any; the second MATCH will fine-filter the results.

Queries involving the OR conditions or relevance sorting are more complex, however.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top