как вместо этого преобразовать оператор sqllite из '=' в MATCH

Я пытаюсь создать решение dbase для потоковой передачи электронной почты. Когда я получаю электронное письмо... Я хочу знать, принадлежит ли это электронное письмо существующей теме.

Итак, я сопоставляю тему т.е. тема = 'крутой братан' соответствует 're: крутой братан'

и я также хочу сопоставить пару отправителя и получателя

ie

(sender = '[email protected]' and receiver = '[email protected]')

OR

(sender ='[email protected]' and receiver = '[email protected]')

для этих точных случаев... этот запрос работал нормально (подробнее см. ">здесь):

(SELECT COUNT(search_email.threadID) FROM search_email 
                                                        WHERE search_email.subject MATCH '%query%'  AND 
                                                        (
                                                            (search_email.sender = '%sender' AND search_email.tos = '%receiver%')
                                                            OR 
                                                            (search_email.sender = '%receiver%' AND search_email.tos = '%sender%')
                                                        )

проблема в том, что у вас есть такой случай:

(sender = 'Amanda Collins [email protected]' and receiver = '[email protected]')

OR

(sender ='Billy Bob [email protected]' and receiver = '[email protected]')

ясно .. предложение MATCH (или какое-то регулярное выражение или что-то в этом роде) здесь в порядке ..

проблема в том, что sqllite не позволяет MATCH работать с OR: вместо него нужен UNION..

но я не мог найти способ преобразовать приведенный выше оператор в оператор, который вместо этого имеет UNION/INTERSECT:

SELECT * FROM search_email WHERE 
                    search_email.subject MATCH '%query%'  INTERSECT SELECT * FROM 
                                        (SELECT * FROM  (SELECT * FROM search_email WHERE 
                                                                                    search_email.sender MATCH '%sender%' 
                                                                                 INTERSECT SELECT * FROM search_email WHERE search_email.tos MATCH '%receiver%' )
                                        UNION 
                                                                            SELECT * FROM(      SELECT * FROM search_email WHERE search_email.sender MATCH '%sender%' 
                                                                                 INTERSECT SELECT * FROM search_email WHERE search_email.tos MATCH '%receiver%'))

есть идеи?

обновление: похоже, что ответ заключается в замене первого intersect на union:

SELECT * FROM search_email WHERE 
                    search_email.subject MATCH '%query%'  UNION SELECT * FROM 
                                        (SELECT * FROM  (SELECT * FROM search_email WHERE 
                                                                                    search_email.sender MATCH '%sender%' 
                                                                                 INTERSECT SELECT * FROM search_email WHERE search_email.tos MATCH '%receiver%' )
                                        UNION 
                                                                            SELECT * FROM(      SELECT * FROM search_email WHERE search_email.sender MATCH '%sender%' 
                                                                                 INTERSECT SELECT * FROM search_email WHERE search_email.tos MATCH '%receiver%'))

но это решение кажется очень неэффективным... компилятору mysql требуется некоторое время, чтобы понять это... есть ли более эффективный способ?


person abbood    schedule 31.12.2012    source источник


Ответы (1)


Использование MATCH или LIKE '%string%' всегда будет очень медленным. Возможно, вы сможете улучшить это с помощью полнотекстового поиска, но вы все равно не продвинетесь слишком далеко.

Есть другой способ сделать это, более эффективный и широко поддерживаемый.

Согласно RFC2822 (и более ранним RFC822) почтовые клиентские программы должны создавать и поддерживать поля в почтовых заголовках, облегчающие поддержку многопоточности. На практике все известные почтовые клиенты поддерживают это. Эти поля:

  • Идентификатор сообщения: обычно выглядит как <[email protected]>
  • In-Reply-To: идентификатор сообщения, на которое был дан ответ.
  • Ссылки: список идентификаторов сообщений, с которыми может быть связано это сообщение.

Если вы извлечете эти заголовки и сохраните их в отдельных столбцах и/или таблицах в своей базе данных, вы сможете легко создавать потоки, используя точное сравнение (без MATCH '%string%'), так что это будет очень быстро.

person mvp    schedule 31.12.2012
comment
гм.. кажется, что все индикаторы подталкивают к решению jwz.. спасибо для напоминания .. ответ присужден - person abbood; 01.01.2013