2012-05-14 8 views
10

Estoy tratando de implementar una forma básica de mostrar comentarios en la forma en que lo hace Hacker News, usando CouchDB. No solo se ordena jerárquicamente, sino también, cada nivel del árbol debe ordenarse mediante una variable de "puntos".CouchDB - comentarios jerárquicos con clasificación. Estilo Hacker News

La idea es que quiero una vista para devolverla en el orden en que excepto, y no hacer muchas llamadas Ajax, por ejemplo, para recuperarlas y hacer que parezcan ordenadas correctamente.

Esto es lo que tengo hasta ahora:

  • Cada documento es un "comentario".
  • Cada comentario tiene una propiedad path que es una lista ordenada que contiene todos sus padres.

Así, por ejemplo, imaginar tengo 4 comentarios (con _id 1, 2, 3 y 4). El comentario 2 es hijos de 1, comentario 3 es hijos de 2, y el comentario 4 también es hijo de 1. Así es como se verían los datos:

{ _id: 1, path: ["1"] }, 
{ _id: 2, path: ["1", "2"] }, 
{ _id: 3, path: ["1", "2", "3"] } 
{ _id: 4, path: ["1", "4"] } 

Esto funciona bastante bien para la jerarquía. Un simple view ya devolverá las cosas ordenadas de la manera que yo quiero.

El problema surge cuando quiero ordenar cada "nivel" del árbol de forma independiente. Entonces, por ejemplo, los documentos 2 y 4 pertenecen a la misma rama, pero están ordenados, en ese nivel, por su ID. En cambio, quiero que se ordenen en función de una variable de "puntos" que quiero agregar a la ruta, pero parece que no puedo entender dónde podría estar agregando esta variable para que funcione de la manera que quiero.

¿Hay alguna manera de hacerlo? Considere que la variable "puntos" cambiará a tiempo.

+0

Hola, Luca. ¿Estás dispuesto a actualizar los comentarios en un gran barrido? Por ejemplo, cada hora, incremente su edad? La respuesta a esa pregunta afecta la respuesta al problema. ¡Gracias! – JasonSmith

+0

Hola @JasonSmith. Por ahora podemos olvidar el problema de la fecha. Imaginemos que cada "comentario" tiene una propiedad de "puntaje" que contiene un valor entero de su puntaje. La pantalla debería mostrar no solo la jerarquía como se explicó anteriormente, sino también ordenar cada "nivel" del árbol en función de esta propiedad de "puntuación". Aquí es donde tengo problemas. Aquí puede ver un ejemplo de lo que intento lograr: http://hckr.iriscou.ch/news/_design/news/_view/items El primero es el comentario raíz, y el resto son niños y niños de niños. . La clave contiene la ruta y también el valor de 'puntuación' como último elemento. –

+0

Sin embargo, como puede ver, esto no funciona porque el segundo último elemento de las claves es el _id del documento real. Esto es necesario para que pueda adjuntar en orden sus hijos (en función de la lógica de ruta). Espero que esto tenga sentido. En cualquier caso, mantener el puntaje como último valor no está funcionando :( –

Respuesta

4

Debido a que cada nivel tiene que ser resuelto de forma recursiva por puntaje, Couch necesita saber el puntaje de cada padre para que esto funcione de la manera que desee.

Tomando su ejemplo, con las siguientes puntuaciones (1: 10, 2: 10, 3, 10, 4:)

En este caso usted desea que el pedido salga como lo siguiente:

.1 
.1.4 
.1.2 
.1.2.3 

necesidades de los documentos a puntuaciones gama de esta manera:

{ _id: 1, path: [1], scores: [10] }, 
{ _id: 2, path: [1, 2], scores: [10,10] }, 
{ _id: 3, path: [1, 2, 3], scores: [10,10,10] }, 
{ _id: 4, path: [1, 4], scores: [10,20] } 

Entonces te Uso la siguiente clave de clasificación en su vista.

emit([doc.scores, doc.path], doc) 

El caminose acostumbra como un desempate, ya que habrá casos en los comentarios de hermanos tienen la misma puntuación exacta. Sin el desempate, sus descendientes podrían perder su agrupación (por cadena de ascendencia).

Nota: Este enfoque devolverá puntajes de bajo a alto, mientras que probablemente desee puntajes (de mayor a menor) y ruta/desempate (de menor a mayor). Por lo que una solución para esto sería para rellenar la matriz puntuaciones con la inversa de cada puntuación de la siguiente manera:

{ _id: 1, path: [1], scores: [0.1] }, 
{ _id: 2, path: [1, 2], scores: [0.1,0.1] }, 
{ _id: 3, path: [1, 2, 3], scores: [0.1,0.1,0.1] }, 
{ _id: 4, path: [1, 4], scores: [0.1,0.2] } 

y luego usar descending=true cuando se solicita la vista.

+0

Además, si va a usar identificadores de correos numéricos, su ruta debe contener valores sin comillas para que no obtenga un comportamiento de clasificación alfabético (por ejemplo, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9). –

+0

Interesante. Sin embargo, esto requiere que actualice todos los puntajes de los niños cuando haya cambiado un puntaje. Gracias, supongo que es una solución posible. Decidí dejar que el cliente haz el trabajo de ordenar jerárquicamente en lugar de Couch. –

+0

Sí, esa es probablemente la forma más fácil. –