2012-01-02 9 views
5

Me gustaría saber cómo realizar pedidos de manera eficiente en Rails. Todos sabemos que se pueden hacer pedidos simple en los carriles con los siguientes métodos:Custom, Efficient, Complex Ordering in Rails 3

Model.order("created_at ASC").limit(10) 

En este caso sólo estoy tirando de las primeras 10 entradas. Si quisiera agregar un orden no delineado en el tiempo, podría crear una columna en el Modelo (p. Ej. Columna custom_ordering) y valores de entrada para ordenar los objetos. En ese caso, simplemente modificaría la llamada de la orden ("custom_ordering ASC").

PERO digamos que deseo hacer un pedido basado en la preferencia pronosticada por un usuario. En este caso, no es factible crear una nueva columna porque cada usuario tiene gustos diferentes. ¿Cuál sería una forma inteligente y eficiente de lograr esta tarea?

Un método sería crear un algoritmo para predecir la calificación de un usuario de un modelo llamado Model_rating (object). Este algoritmo escupiría un valor entero positivo de su calificación. Si sigo este camino, ¿cómo ordenaré eficientemente el Modelo?

Otro método sería establecer el algoritmo como un model_entry.user_preference (usuario). Entonces podría ordenar por:

Model.all.sort! { |b, a| a.user_preference(user) <=> b.user_preference(user) } 

Pero esto me parece poco eficiente. Tiene que llamar a todas las entradas del modelo y luego ordenarlas, lo que, incluso si usa métodos de clasificación eficientes como fusión o clasificación de burbujas, obtiene un rendimiento deficiente en los modelos con un gran número de entradas.

¿Hay otras rutas que no estoy considerando? Puede alguien señalarme la dirección correcta?

Respuesta

0

En esta solución, supongo que el cálculo de la orden preferida del usuario es costoso y que el conjunto que está solicitando no se actualiza con frecuencia.

Lo que podría hacer es calcular el orden cada cierto tiempo (en una tarea en segundo plano) y almacenar el orden calculado en una tabla por usuario.

Alternativamente, si no tiene muchos usuarios, puede guardar en una tabla separada el puntaje de cada modelo por usuario, y ordenar por ese valor en una combinación. Estos valores también pueden ser recalculados regularmente.

+0

sí, parecen opciones viables. ¿Cree que cualquiera de estos enfoques sería cómo un sitio tan grande como Facebook ordena un suministro de noticias? En estos casos, tiene muchas entradas de tabla y muchos usuarios. – jay

+0

En el caso de Facebook, creo que almacenan un suministro de noticias por persona por separado. No creo que las "historias" se compartan entre las personas. Estas historias usan recursos compartidos (álbumes, comentarios, etc.)) pero cada historia en tu línea de tiempo está hecha para ti. (Al menos, así es como lo construiría) –

+0

¡bueno, muy interesante! ¡siempre esclarecedor para discutir estas cosas con los demás! muchas gracias por su entrada – jay

0

La clasificación de burbuja no es eficiente.

Si está hablando de ordenar un único modelo, entonces es cierto que todas las entradas de clasificación serían atributos de ese modelo. Si cada usuario puede especificar su propia preferencia de clasificación, entonces se reduce a un atributo o una lista de atributos. Guarde esa lista como una preferencia de usuario, luego construya la consulta dinámicamente. Diablos, guarde el código real como preferencia y haga una evaluación sobre él.

Pero, incluso SQL eficiente se rompe cuando el número de registros se acerca a un umbral. En ese caso, necesitas una nueva herramienta.

Puede utilizar una implementación de búsqueda adecuada, que inherentemente incluye la clasificación. Yo uso Solr con la gema de la mancha solar. Y parece que Sphinx con la gema pensamiento-esfinge también tiene buena tracción.