2015-12-30 5 views
2

Я хочу написать логический полнотекстовый поисковый запрос в MySQL. Но я хочу, чтобы иметь результаты в таком порядке: (. > означает выше)MySQL логический полнотекстовый поиск с подвыражениями

Exact Matches>Including all the words>Including some of the words

С помощью следующего запроса, я получаю точные совпадения выше:

SELECT *, MATCH(name,description,address) 
AGAINST('>("word1 word2 word3") <(word1 word2 word3)' IN BOOLEAN MODE) 
AS score FROM samples WHERE MATCH(name,description,address) 
AGAINST('>("word1 word2 word3") <(word1 word2 word3)' IN BOOLEAN MODE) ORDER BY score DESC 

Со следующим запросом я получаю документы, которые содержат все слова выше, чем те, которые содержат часть запроса:

SELECT *, MATCH(name,description,address) 
AGAINST('>(+word1 +word2 +word3) <(word1 word2 word3)' IN BOOLEAN MODE) 
AS score FROM samples WHERE MATCH(name,description,address) 
AGAINST('>(+word1 +word2 +word3) <(word1 word2 word3)' IN BOOLEAN MODE) ORDER BY score DESC 

Но я хочу объединить эти два вопроса. Это лучшее, что я дошел до сих пор, но я не получаю результаты, которые я хочу.

SELECT *, MATCH(name,description,address) 
AGAINST('>("word1 word2 word3") <(>(+word1 +word2 +word3) <(word1 word2 word3))' IN BOOLEAN MODE) 
AS score FROM samples WHERE MATCH(name,description,address) 
AGAINST('>("word1 word2 word3") <(>(+word1 +word2 +word3) <(word1 word2 word3))' IN BOOLEAN MODE) 
ORDER BY score DESC 

Есть ли способ сделать это без UNIONs?

+1

Невозможно сделать это, если есть более двух слов, чтобы соответствовать как 'match (..) против ('> frist second third')'. Возможно, вам придется идти только с «union». –

ответ

1

Будет ли это работать?

SELECT *, 
     MATCH (name,description,address) 
      AGAINST ('"word1 word2 word3"' IN BOOLEAN MODE) score_exact, 
     MATCH (name,description,address) 
      AGAINST ('+word1 +word2 +word3' IN BOOLEAN MODE) score_all, 
     MATCH (name,description,address) 
      AGAINST ('word1 word2 word3' IN BOOLEAN MODE) score_some 
    FROM samples 
    WHERE MATCH (name,description,address) 
      AGAINST ('word1 word2 word3' IN BOOLEAN MODE) 
ORDER BY score_exact DESC, score_all DESC, score_some DESC 
+0

Ничего себе очень творческий! Я думаю, это сработает, я должен проверить это. – Aidin

1
(SELECT *, 
     1 AS sort_order,  -- top priority to exact match 
     1.0 AS extra_ordering 
     ... WHERE txt = 'aaaa bbbb cccc') 
UNION ALL 
(SELECT *, 
     2 AS sort_order,  -- next to all words exist 
     MATCH(txt) AGAINST("+aaaa +bbbb +cccc" IN BOOLEAN MODE) 
     ... WHERE MATCH(txt) AGAINST("+aaaa +bbbb +cccc" IN BOOLEAN MODE) 
UNION ALL 
(SELECT *, 
     3 AS sort_order,  -- finally "any" words 
     MATCH(txt) AGAINST("aaaa bbbb cccc" IN BOOLEAN MODE) 
     ... WHERE MATCH(txt) AGAINST("aaaa bbbb cccc" IN BOOLEAN MODE) 
ORDER BY sort_order ASC, extra_ordering DESC 
LIMIT 1; -- to get the 'best' 
+0

Моя проблема с профсоюзами заключается в том, что он возвращает повторяющиеся записи, потому что столбец оценки отличается, хотя первичный ключ равен! – Aidin

+0

Не будет дубликатов из-за столбца, который я добавил: 'sort_order'. И я добавил 'LIMIT 1'. –

+0

Мне нужно получить больше результатов, и порядок сортировки отличается для каждого подзапроса, если строка появляется в нескольких подзапросах, она будет дублироваться. – Aidin

Смежные вопросы