Estoy tratando de hacer una búsqueda de texto completo en tres separado tablas y ordenar los resultados por relevancia. Durante mis búsquedas por la respuesta, me enteré de que no los puedo usar de búsqueda de texto en varias tablas. Así que he añadido una nueva fulltext index para cada columna que desee buscar. Ahora el problema es que me puede hacer la búsqueda, pero no puedo hacer la clasificación como me gustaría.

Aquí está mi mesas

CREATE TABLE books (
 bookID int(11) NOT NULL AUTO_INCREMENT,
 title varchar(300) NOT NULL,
 authorID int(11) NOT NULL,
 FULLTEXT KEY title (title)
)

CREATE TABLE IF NOT EXISTS authors (
 authorID int(11) NOT NULL AUTO_INCREMENT,
 authorNamevarchar(200) NOT NULL,
 FULLTEXT KEY authorName(authorName)
);

CREATE TABLE IF NOT EXISTS chapters (
 chapterID int(11) NOT NULL AUTO_INCREMENT,
 bookID int(11) NOT NULL,
 content longtext NOT NULL,
 FULLTEXT KEY content (content)
);

Y mi consulta sql. Esto es donde estoy atascado.

SELECT *, 
 MATCH(books.title) AGAINST('$q') as tscore,
 MATCH(authors.authorName) AGAINST('$q') as ascore
 MATCH(chapters.content) AGAINST('$q') as cscore
FROM books 
LEFT JOIN authors ON books.authorID = authors.authorID 
LEFT JOIN chapters ON books.bookID = chapters.bookID 
WHERE 
 MATCH(books.title) AGAINST('$q')
 OR MATCH(authors.authorName) AGAINST('$q')
 OR MATCH(chapters.content) AGAINST('$q')
ORDER BY ???? DESC

Ahora con esta consulta me puede hacer la clasificación por títulos, autores o contenidos. Lo que quiero hacer es obtener la relevancia para todas las tres de las columnas y el orden de los resultados por que.

Y sí, estoy consciente de que otros motores de búsqueda como lucene o de la esfinge, pero no estoy de planificación para el uso de ellos ahora.

Gracias de antemano.

OriginalEl autor keune | 2010-11-19

3 Comentarios

  1. 34

    Usted debería ser capaz de añadir el tscore, ascore, y cscore valores en la cláusula ORDER BY.

    Intente esto:

    SELECT *, 
     MATCH(books.title) AGAINST('$q') as tscore,
     MATCH(authors.authorName) AGAINST('$q') as ascore,
     MATCH(chapters.content) AGAINST('$q') as cscore
    FROM books 
    LEFT JOIN authors ON books.authorID = authors.authorID 
    LEFT JOIN chapters ON books.bookID = chapters.bookID 
    WHERE 
     MATCH(books.title) AGAINST('$q')
     OR MATCH(authors.authorName) AGAINST('$q')
     OR MATCH(chapters.content) AGAINST('$q')
    ORDER BY (tscore + ascore + cscore) DESC
    exactamente. gracias.
    Me ayudó a cargas. Gracias!
    Muy bonito, lo que yo necesitaba para mi proyecto!

    OriginalEl autor Ike Walker

  2. 0

    @Ike Walker solución es grande, sin embargo en mi caso yo quería rodar hasta el uno-a-muchos de los resultados en una sola fila por cada resultado de búsqueda. Riffs en @Ike Walker solución aquí es cómo conseguí el trabajo realizado:

    Esquema:

    T1: Articles
    T2: Comments (many comments to one article)

    Índices:

    ALTER TABLE articles ADD FULLTEXT title_index (title)
    ALTER TABLE articles ADD FULLTEXT body_index (body)
    ALTER TABLE comments ADD FULLTEXT comment_index (comment)

    SQL:

    SELECT 
        articles.title, 
        SUM(MATCH(articles.title) AGAINST('$q') + 
        MATCH(articles.body) AGAINST('$q') + 
        MATCH(comments.comment) AGAINST('$q')) as relevance 
    FROM 
        articles 
    LEFT JOIN 
        comments ON articles.id = comments.article_id 
    WHERE 
        MATCH(articles.title) AGAINST('$q') 
        OR MATCH(articles.body) AGAINST('$q') 
        OR MATCH(comments.comment) AGAINST('$q') 
    GROUP BY 
        articles.id 
    ORDER BY 
        relevance DESC

    Nota: Si desea agregar pesos a cada campo se podría hacer algo como.

    SUM((MATCH(articles.title) AGAINST('$q')*3) + 
            (MATCH(articles.body) AGAINST('$q')*2) + 
            MATCH(comments.comment) AGAINST('$q')) as relevance 

    En este caso, el título habría 3x, cuerpo 2x el valor de una coincidencia en los comentarios.

    OriginalEl autor Justin Vincent

  3. -1

    Depende de lo que desee ordenar. Usted puede ordenar por autor, título, capítulo contenido con este

    ORDER BY MATCH(authors.authorName) DESC ,MATCH(books.title) DESC ,MATCH(chapters.content) DESC

    la idea de que cuando encuentre el nombre de los autores, es más relevante que cuando se encuentra en el título, que a su vez es más relevante que lo encuentre en el capítulo de texto. Usted podría también ordenar por el total de la relevancia con

    ORDER BY MATCH(authors.authorName) + MATCH(books.title) + MATCH(chapters.content) DESC

    pero que podría dar impar resultados, como algo donde el texto de búsqueda solo se muestra en el capítulo de contenidos que pudieran aparecer antes de que el título.

    no funciona yo lo he probado….usted puede hacer la ORDEN POR PARTIDO(..) en CONTRA() que hace lo mismo que la segunda consulta

    OriginalEl autor Kibbee

Dejar respuesta

Please enter your comment!
Please enter your name here