Cómo modelar hashtags con nodejs y mongodb

7

Arquitectura existente: servidor nodejs con back-end mongodb.

Aparecen cadenas que describen imágenes que pueden tener #hashtags en ellas.

Deseo extraer los hashtags de las cadenas, almacenarlos y asociar la imagen con ese hashtag.

Por ejemplo, una imagen se carga con 'divirtiéndose en #bandcamp #nyc'

Se extraen

#bandcamp y #nyc .

  • Si no existen como hashtags ya, se crean y la imagen se asocia a ambos.

  • Si existen, eso se reconoce y la imagen está asociada a ambas.

Por lo tanto, será posible crear una consulta de búsqueda de Mongo que obtenga todas las imágenes para un hashtag o varios hashtags.

Soy nuevo en Nosql, entiendo que en el relacional tendría:

  • hashtags de mesa
  • imágenes de la tabla
  • table imageshashtags

con una relación de muchos a muchos. Una imagen puede tener muchas etiquetas hash y un hashtag puede tener muchas imágenes.

¿Qué tipo de enfoque es adecuado con mongo? Después de leer q & a me gusta esto: enlace

Veo que puedo implementar un documento secundario en el documento de imagen con las etiquetas. ¿Es eso eficiente para buscar y recuperar?

Luego podría usar enlace - ¿reducir mapa?

Así que termina con:

colección de imágenes con etiquetas subdocumento colección de etiquetas

  • las imágenes documentan con etiquetas subdocumento con etiquetas extraídas y agregadas cuando se crea la imagen, y se agrega una nueva etiqueta a la colección si aún no está presente (es decir, las etiquetas deben ser únicas)

también crea la etiqueta en la colección de etiquetas y ejecuta map map reduce.

¿Eso es sonido? ¿Estoy entendiendo las cosas correctamente y mi enfoque es sensible?

    
pregunta Dave 16.03.2013 - 04:41

2 respuestas

3

Almacene los hashtags en una matriz dentro de un documento.

Ese es el beneficio de tener documentos: simplemente puedes anidarlos. Y, en este caso particular, es trivial:

{
    "_id": 123,
    "file": "c43a5f46-kitten.png",
    "description": "My kitten :3 #kittens #cute"
    "hashtags": ["kittens", "cute", "cat", "animals"]
}

(Agregué algunas etiquetas "sinónimas", esto se puede hacer automáticamente al buscar algún otro documento).

Esta es la solución más natural para una base de datos orientada a documentos:

  • La búsqueda de documentos por hashtags es trivial si solo agrega un índice, así como la inserción, actualización y eliminación de hashtags en documentos aleatorios también es trivial
  • Insertar, actualizar y eliminar de forma masiva es un poco complicado, porque probablemente querrá dividir estas operaciones en múltiples "lotes", pero aún así es manejable y no es difícil de implementar.
  • Las agregaciones complejas se pueden realizar con la canalización de agregación estándar o map-reduce

Por otra parte, si elige un estilo relacional, tendrá un gran problema al reinventar un JOIN de SQL dentro del código de su aplicación. Este es uno de los anti-patrones más comunes del uso de MongoDB (y otros). Aquí hay un pseudocódigo muy típico:

for (HashTag tag: mongodb.hashtags.find()) {
   for (Image img: mongodb.images.find(
           new Document("_id", new tag.getImageId()))) {
       // ...
   }
}

Esto es ineficiente, no escalable, y simplemente estás reinventando una rueda. Usando esto, probablemente terminará con la complejidad de O(N*M) debido a los bucles dentro de su código. Si eligieras SQL con claves externas, tendrías algo como O(N*log(M)) o incluso O(N+M) .

No hay tablas (relaciones) ni claves externas en MongoDB . No los inventes, por favor. Utilice SQL en su lugar, si es necesario. De hecho, le sugiero que utilice SQL en lugar de MongoDB, a menos que sus datos realmente estén formados por documentos.

Ejemplos típicos de documentos son configuraciones, formularios y tal vez sesiones de usuario. Los que normalmente no encajan bien en las tablas debido a la estructura "aleatoria".

    
respondido por el scriptin 14.11.2015 - 21:40
-1

Yo crearía dos tablas. MongoDB es muy flexible. Solo digo dos tablas en lugar de una tabla con los dos campos, "imagen" y "matriz de etiquetas hash", porque eso dificultaría la consulta de etiquetas hash.

También debe utilizar mongoose para conectarse a su base de datos, es fácil y flexible en comparación con la inserción directa en MongoDB.

Las dos tablas deben ser:

  1. un campo, Imágenes justas, (mongo crea automáticamente una ID única para cada entrada (_id))

  2. Una base de datos con dos campos, "cadenas de etiquetas #hash" y "una matriz de identificadores únicos correspondientes a las imágenes en la Tabla de imágenes.

Después de recibir su imagen, analice las etiquetas hash y guarde las cadenas en una variable local. Inserte la imagen en la primera tabla y devuelva el identificador único (_id) para la imagen.

Realice una subida a la segunda tabla para cada etiqueta #hash y añada una ID de imagen (_id) a la que pertenece. [el campo de identificación de la imagen será una matriz] (upsert buscará una coincidencia _id y creará un nuevo documento si no existe uno. Requiere jQuery).

Recomiendo esta estructura de base de datos por dos razones principales:

  1. Solo almacena una copia de cada imagen.

  2. Lo configuró para hacer llamadas de consulta fáciles a #hash etiquetas particulares.

Todo lo que tomaría sería consultar la tabla de hashtag y devolver la matriz de ID de imagen, luego iterar sobre la matriz de ID de imagen haciendo llamadas a la tabla de imágenes. Déjame saber si deseas alguna aclaración con esto, a veces tengo problemas para explicarme con claridad.

    
respondido por el Steven 18.03.2013 - 22:16

Lea otras preguntas en las etiquetas