OK, więc próbuję przeprowadzić wyszukiwanie pełnotekstowe w wielu kolumnach, coś prostego:
SELECT * FROM pages WHERE MATCH(head, body) AGAINST('some words' IN BOOLEAN MODE)
Teraz chcę uporządkować według trafności (ile słów zostało znalezionych?), Co udało mi się zrobić z czymś takim:
SELECT * , MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE) AS relevance
FROM pages
WHERE MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE)
ORDER BY relevance
Teraz nadchodzi część, w której się gubię, chcę nadać priorytet trafności w head
kolumnie.
Wydaje mi się, że mógłbym utworzyć dwie kolumny adekwatności, jedną dla head
i jedną dla body
, ale w tym momencie przeprowadziłbym nieco to samo wyszukiwanie w tabeli trzy razy, a dla tego, co wykonuję tę funkcję, wydajność jest ważna, ponieważ zapytanie zostanie połączone i dopasowane do innych tabel.
Zatem moje główne pytanie brzmi : czy istnieje szybszy sposób wyszukiwania trafności i nadawania priorytetów niektórym kolumnom? (A jako bonus, być może nawet licząc trafność, ile razy słowa występują w kolumnach?)
Wszelkie sugestie lub porady byłyby świetne.
Uwaga: uruchomię to na serwerze LAMP. (WAMP w testach lokalnych)
źródło
Odpowiedzi:
To może dać zwiększenie znaczenia dla części głowy, które chcesz. Nie podwoi tego, ale może być wystarczająco dobry dla twojego dobra:
SELECT pages.*, MATCH (head, body) AGAINST ('some words') AS relevance, MATCH (head) AGAINST ('some words') AS title_relevance FROM pages WHERE MATCH (head, body) AGAINST ('some words') ORDER BY title_relevance DESC, relevance DESC -- alternatively: ORDER BY title_relevance + relevance DESC
Alternatywą, którą również chcesz zbadać, jeśli masz elastyczność w przełączaniu silnika DB, jest Postgres . Pozwala ustawić wagę operatorów i bawić się rankingiem.
źródło
MATCH
instrukcji, ze względu na sposób, w jaki MySQL działa wewnętrznie.ALTER TABLE talk_webpages ADD FULLTEXT(head)
orazALTER TABLE talk_webpages ADD FULLTEXT(head, body)
Tylko dodawanie dla tego, kto może potrzebować ... Nie zapomnij zmienić tabeli!
ALTER TABLE table_name ADD FULLTEXT(column_name);
źródło
TABLE_CATALOG
= 'def' ANDTABLE_SCHEMA
= DATABASE () ANDTABLE_NAME
= 'tablename' ANDINDEX_NAME
= 'indexname';Nigdy tego nie robiłem, ale wygląda na to
Powinien dać podwójną wagę zapałkom znalezionym w głowie.
Po prostu przeczytaj ten komentarz na stronie z dokumentami. Pomyślałem, że może być dla Ciebie wartościowy:
SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance FROM table WHERE MATCH ('Content') AGAINST('+keyword1+keyword2' IN BOOLEAN MODE) HAVING Relevance > 0.2 ORDER BY Relevance DESC
Więc może się wydawać, że nie musisz się martwić o dwukrotne wywołanie wyszukiwania pełnotekstowego, chociaż nadal powinieneś "użyć EXPLAIN, aby to udowodnić"
źródło
Ja też się tym bawiłem. Jednym ze sposobów dodania dodatkowego ciężaru jest opcja ZAMÓWIENIE według kodu.
Na przykład, jeśli dopasowujesz 3 różne kolumny i chcesz bardziej ważyć niektóre kolumny:
SELECT search.*, MATCH (name) AGAINST ('black' IN BOOLEAN MODE) AS name_match, MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE) AS keyword_match, MATCH (description) AGAINST ('black' IN BOOLEAN MODE) AS description_match FROM search WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE) ORDER BY (name_match * 3 + keyword_match * 2 + description_match) DESC LIMIT 0,100;
źródło
SELECT search.*, (MATCH (name) AGAINST ('black' IN BOOLEAN MODE) * 3) + (MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE)*2 + MATCH (description) AGAINST ('black' IN BOOLEAN MODE)) AS totalScore , FROM search WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE) ORDER BY totalScore DESC LIMIT 0,100;