De acuerdo, estoy tratando de hacer una búsqueda de texto completo en varias columnas, algo simple como esto:
SELECT * FROM pages WHERE MATCH(head, body) AGAINST('some words' IN BOOLEAN MODE)
Ahora quiero ordenar por relevancia, (¿cuántas de las palabras se encuentran?) Que he podido hacer con algo como esto:
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
Ahora aquí viene la parte donde me pierdo, quiero priorizar la relevancia en la head
columna.
Supongo que podría hacer dos columnas de relevancia, una para head
y otra para body
, pero en ese momento estaría haciendo la misma búsqueda en la tabla tres veces, y para lo que hago esta función, el rendimiento es importante, ya que La consulta se combinará y comparará con otras tablas.
Entonces, mi pregunta principal es , ¿existe una forma más rápida de buscar relevancia y priorizar ciertas columnas? (¿Y como beneficio adicional, posiblemente incluso hacer que la relevancia cuente el número de veces que las palabras aparecen en las columnas?)
Cualquier sugerencia o consejo sería genial.
Nota: Ejecutaré esto en un servidor LAMP. (WAMP en pruebas locales)
fuente
Respuestas:
Esto puede dar una mayor relevancia a la parte principal que desee. No lo duplicará, pero posiblemente sea lo suficientemente bueno para usted:
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
Una alternativa que también desea investigar, si tiene la flexibilidad de cambiar el motor de base de datos, es Postgres . Permite establecer el peso de los operadores y jugar con el ranking.
fuente
MATCH
declaraciones, debido a la forma en que MySQL funciona internamente.ALTER TABLE talk_webpages ADD FULLTEXT(head)
yALTER TABLE talk_webpages ADD FULLTEXT(head, body)
Solo agregando para quien pueda necesitar ... ¡No olvides modificar la tabla!
ALTER TABLE table_name ADD FULLTEXT(column_name);
fuente
TABLE_CATALOG
= 'def' ANDTABLE_SCHEMA
= DATABASE () ANDTABLE_NAME
= 'tablename' ANDINDEX_NAME
= 'indexname';Nunca lo he hecho, pero parece que
Debe dar un doble peso a los fósforos que se encuentran en la cabeza.
Solo lea este comentario en la página de documentos , creo que podría ser de valor para usted:
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
Por lo tanto, parecería que no necesita preocuparse por llamar dos veces a la búsqueda de texto completo, aunque aún debe "usar EXPLAIN para probar esto"
fuente
Yo también estaba jugando con esto. Una forma de agregar peso adicional es en el área ORDENAR POR del código.
Por ejemplo, si estuviera haciendo coincidir 3 columnas diferentes y quisiera ponderar más ciertas columnas:
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;
fuente
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;