38 votos

Óptima de la arquitectura de datos para el etiquetado, las nubes, y la búsqueda (como StackOverflow)?

Me encantaría saber cómo Stack Overflow del etiquetado y la búsqueda de arquitectura, porque parece que funciona bastante bien.

¿Qué es una buena base de datos/modelo de búsqueda si quiero hacer todo lo siguiente:

  1. El almacenamiento de Etiquetas en diferentes entidades, (cómo normalizado? es decir, la Entidad, de la Etiqueta, y Entity_Tag tablas?)
  2. La búsqueda de elementos con particular etiquetas
  3. La construcción de una nube de etiquetas de todas las etiquetas que se aplican a un determinado conjunto de resultados de búsqueda
  4. Cómo mostrar una lista de etiquetas para cada elemento en un resultado de búsqueda?

Tal vez tenga sentido para almacenar las etiquetas en una forma normalizada, pero también como un espacio delimitado por la cadena para los fines de la #2, #4, y tal vez #3. Los pensamientos?

He oído decir que Stack Overflow utiliza Lucene para la búsqueda. Es eso cierto? He escuchado un par de podcasts discutiendo optimización SQL, pero nada acerca de Lucene. Si hacen uso de Lucene, me pregunto cuánto de los resultados de la búsqueda viene de Lucene, y si el "drill-down" nube de etiquetas viene de Lucene.

57voto

Winston Fassett Puntos 1810

Wow acabo de escribir un gran post y de LO estrangulado y colgado en él, y cuando me he golpeado el botón atrás para volver a enviar, el marcado editor estaba vacía. aaargh.

Así que aquí voy de nuevo...

Respecto de Stack Overflow, resulta que el uso de SQL server 2005 de búsqueda de texto completo.

Con respecto a la de OS proyectos recomendados por @Subvención:

  • *DotNetKicks utiliza la base de datos para el etiquetado y Lucene para la búsqueda de texto completo. Parece ser que no hay manera de combinar una búsqueda de texto completo con una etiqueta de búsqueda
  • Kigg utiliza Linq to SQL para la búsqueda y de las preguntas del tag. Ambas consultas unirse Historias->StoryTags->Etiquetas.
  • Ambos proyectos cuentan con un 3-tabla de enfoque para el etiquetado como todo el mundo en general parece recomendar

También encontré algunas otras preguntas sobre LO que había pasado por alto:

Lo que estoy haciendo actualmente para cada uno de los elementos que he mencionado:

  1. En la DB, 3 tablas: Entidad, Etiqueta, Entity_Tag. Yo uso la DB:
    • Construir de todo el sitio nubes de etiqueta
    • buscar por etiqueta (es decir, la url, como LO es /preguntas/tagged/ASP.NET)
  2. Para la búsqueda puedo usar Lucene + NHibernate.Búsqueda
    • Las etiquetas son concat había en un TagString que es indexado por Lucene
      • Así que tengo todo el poder de la Lucene motor de consulta (Y / O / NO consultas)
      • Puedo búsqueda para el texto y filtrar por etiquetas al mismo tiempo
      • Lucene analizador combina palabras para una mejor etiqueta de búsquedas (es decir, una etiqueta de la búsqueda para "probar" también encontrará cosas con la etiqueta "pruebas")
    • Lucene devuelve un potencial enorme conjunto de resultados, que me paginar 20 resultados
    • A continuación, NHibernate carga el resultado de Entidades por el Id, ya sea desde la DB, o de la Entidad de caché
    • Así que es muy posible que los resultados de la búsqueda con 0 hits a la DB
  3. No hacer esto, pero creo que probablemente voy a tratar de encontrar una manera de construir la nube de tags de la TagString en Lucene, en lugar de tomar otro golpe DB
  4. No se ha hecho todavía, pero probablemente voy a la tienda de la TagString en la base de datos para que yo pueda mostrar de una Entidad en la lista de Etiquetas sin tener que hacer 2 más se une.

Esto significa que siempre que una Entidad etiquetas son modificados, tengo que:

  • Insertar nuevas Etiquetas que ya no existen
  • Insertar/Eliminar de la tabla EntityTag
  • Actualización De La Entidad.TagString
  • Actualización el índice de Lucene para la Entidad

Dado que la relación de lecturas y escrituras es muy grande en mi aplicación, creo que estoy bien con esto. El único que realmente consume mucho tiempo parte es Lucene indexación, porque Lucene sólo puede insertar y eliminar de su índice, así que tengo que volver a indexar toda la entidad con el fin de actualizar el TagString. No estoy entusiasmado con eso, pero creo que si lo hago en un subproceso de fondo, que va a estar bien.

El tiempo dirá...

5voto

Grant Puntos 190

No sé si calificar como óptimo, pero ambos DotNetKicks y Kigg son de código abierto clon de digg implementaciones. Usted puede ver cómo se están haciendo las etiquetas y búsqueda.

Mi mejor conjetura sin mucha deliberación :)

  1. Nunca me gusta la idea de serializar varios valores en un solo campo, así delimitado por las cadenas almacenadas en un campo no me atrae... podría funcionar para adyacencia de caminos con árboles, pero los que están siempre ordenadas y etiquetas no tiene que ser. Esto parece que sería de impuestos el operador LIKE de trabajo que usted puede hacer para encontrarlos.

Así que mi primera toma es probablemente Entidad -> EntityTag <- Tag.

  1. Este enfoque hace que la búsqueda de elementos a través de la Etiqueta bastante fácil, unirse de nuevo a través de EntityTag, llamar a un día.

  2. Usted necesita una operación secundaria aquí para seleccionar las distintas etiquetas para el conjunto de resultados. Así que un.) tire del conjunto de resultados, b.) normalizar la etiqueta de espacio. Yo creo que sí, esto no importa cuál es la respuesta a #1 -- incluso relleno de etiquetas en un campo todavía rendimiento etiquetas duplicadas (y tiene deserializar ellos para llevar a cabo esta op--así que más trabajo, otro argumento para un completo enfoque relacional).

  3. Aún fácil. Aquí es un área donde la serializado enfoque funciona mejor. No hay necesidad de unirse para etiquetas hijo, que está justo en la Entidad. Que dijo, sacando 0..n etiquetas a través de las dos de la tabla de combinación no parece demasiado difícil para mí. Si usted está hablando de perf consideraciones, construir normalizado primero y luego optimizar a través de la caché o denorm.

La otra opción es "hacer ambas cosas". Esto se siente como una prematura de optimización, pero se puede hacer la plena enfoque normalizado para apoyar cualquier etiqueta centrado en las operaciones y serializar a persistir a tener un sin normalizar la versión de la derecha que hay en la Entidad. Un poco más de trabajo, algo de potencial para la caída de sincronización si no está totalmente cubierto, pero lo mejor de ambos mundos si hay limitaciones reales a la forma normalizada en sus casos de uso.

Lucene es interesante también, usted puede declarar metadatos específicos en los índices IIRC, por lo que potencialmente podría aprovechar de búsqueda de etiquetas de esta manera. Mi sospecha es que, si usted va demasiado lejos por este camino, entonces usted termina encima de tener algunas disparidades entre lo que se debe almacenar en la base de datos y el índice en algún momento. Puedo hablar favorablemente sobre Lucene, es muy capaz y fácil de usar ... creo .El texto utilizado por las capacidades de búsqueda y se apoyó a todos weblogs.asp.net antes de cambiar a Servidor de la Comunidad. Me gustaría que se adhieren a ella por la búsqueda de texto completo si MSSQL no está en la imagen/suficiente, resolver las cuestiones de etiqueta en la base de datos de la omi.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X