query fulltext fts php mysql algorithm

php - fulltext - fts mysql



Algoritmo de Popularidad (4)

Me gustaría llenar la página de inicio de mi sitio de imágenes enviadas por el usuario con las ilustraciones "más populares" cargadas.

Estas son las medidas que tengo disponibles:

  • Cuántas personas han favorecido esa ilustración
    • votes tabla de votes incluye la fecha de votación
  • Cuando la ilustración fue cargada
    • illustration tabla de illustration tiene fecha de creación
  • Cantidad de comentarios (no tan buenos como los comentarios máximos total alrededor de 10 en este momento)
    • comments tabla de comentarios tiene fecha de comentario

He buscado, pero no quiero que la autoridad del usuario juegue un papel, pero la mayoría de los algoritmos incluyen eso.

También necesito averiguar si es mejor hacer el cálculo en MySQL que obtiene los datos o si debe haber un método PHP / cron cada hora más o menos.

Solo necesito 20 ilustraciones para completar la página de inicio. No necesito ningún tipo de búsqueda de estos datos.

¿Cómo peso la edad contra los votos? ¿Seguramente un sitio con menos envío necesita menos peso en la fecha agregada?


Algo como:

(count favorited + k) * / time since last activity

Cuanto mayor es k menos peso tiene el número de personas que lo ha favorecido.

También podría cambiar el tiempo a algo así como la hora en que apareció por primera vez + la hora de la última actividad, esto garantizaría que las ilustraciones antiguas desaparecerían con el tiempo.


No tengo ideas útiles en lo que respecta al agoritmo real, pero en términos de implementación, sugiero almacenar en caché el resultado en alguna parte, con una actualización periódica: si el resultado del cálculo resulta en una consulta cara, probablemente no lo haga querer ralentizar tus tiempos de respuesta.


Obviamente, hay algo de subjetividad en esto: no existe un algoritmo "correcto" para determinar el equilibrio adecuado, pero comenzaría con algo así como votos por unidad de edad. MySQL puede hacer cálculos básicos para que pueda pedir que se ordene por el cociente de votos a lo largo del tiempo; sin embargo, por motivos de rendimiento, podría ser una buena idea guardar en caché el resultado de la consulta. Tal vez algo como

SELECT images.url FROM images ORDER BY (NOW() - images.date) / COUNT((SELECT COUNT(*) FROM votes WHERE votes.image_id = images.id)) DESC LIMIT 20

pero mi SQL está oxidado ;-)

Tomar un promedio simple será, por supuesto, un sesgo a favor de que aparezcan nuevas imágenes en la página principal. Si desea eliminar ese sesgo, podría contar, por ejemplo, los votos que ocurrieron dentro de un determinado límite de tiempo después de la publicación de la imagen. Para las imágenes que son más recientes que ese límite de tiempo, tendría que normalizar multiplicando el número de votos por el límite de tiempo y dividiéndolo por la edad de la imagen. O, como alternativa, podría dar a los votos un peso variable continuo, algo así como exp(-time(vote) + time(image)) . Y así sucesivamente ... dependiendo de qué tan particular sea usted acerca de lo que hará este algoritmo, podría tomar un poco de experimentación para averiguar qué fórmula da los mejores resultados.


Muchos sitios que utilizan algún tipo de ranking de popularidad lo hacen mediante el uso de un algoritmo estándar para determinar un puntaje y luego decaer eternamente con el tiempo. Lo que he encontrado funciona mejor para los sitios con menos tráfico es un multiplicador que da una bonificación al nuevo contenido / actividad: es esencialmente el mismo, pero el puntaje deja de cambiar después de un período de tiempo de su elección.

Por ejemplo, aquí hay un pseudo-ejemplo de algo que quizás quieras probar. Por supuesto, querrás ajustar la cantidad de peso que atribuyes a cada categoría en función de tu propia experiencia con tu sitio. Los comentarios son raros, pero requieren más esfuerzo del usuario que un favorito / voto, por lo que probablemente deberían recibir más peso.

score = (votes / 10) + comments age = UNIX_TIMESTAMP() - UNIX_TIMESTAMP(date_created) if(age < 86400) score = score * 1.5

Este tipo de enfoque daría una bonificación a los nuevos contenidos cargados en el día anterior. Si quisiera abordar esto de manera similar solo para el contenido que se ha marcado como favorito o que se ha comentado recientemente, puede agregar algunas restricciones WHERE en su consulta que capturen la puntuación del DB.

En realidad, hay dos grandes razones para NO calcular esta clasificación sobre la marcha.

  1. Requerir que su DB obtenga todos esos datos y haga un cálculo en cada carga de página solo para reordenar los artículos, resulta en una consulta costosa.
  2. Probablemente, un resultado más pequeño, pero si tiene una cantidad relativamente pequeña de actividad en el sitio, pequeños cambios en el ranking pueden hacer que el contenido se mueva de manera bastante drástica.

Esto lo deja con el almacenamiento en memoria caché de los resultados periódicamente o la configuración de un trabajo cron para actualizar una nueva columna de base de datos con este puntaje por el que se clasifica.