Come modellare hashtag con nodejs e mongodb

7

Architettura esistente: server nodejs con backend mongodb.

Ho delle stringhe che arrivano descrivendo immagini che possono contenere #hashtag in esse.

Desidero estrarre gli hashtag dalle stringhe, archiviare gli hashtag e associare l'immagine con quell'hashtag.

Quindi ad es. un'immagine viene caricata con "divertendosi su #bandcamp #nyc"

#bandcamp e #nyc vengono estratti.

  • Se non esistono già come hashtag, vengono creati e l'immagine è associata a entrambi.

  • Se esistono, viene riconosciuto e l'immagine è associata a entrambi.

Quindi sarà possibile creare una query di ricerca di mongo che recuperi tutte le immagini per un hashtag o più hashtag.

Sono nuovo di nosql, capisco che in relazionale avrei:

  • hashtag della tabella
  • immagini tabella
  • tabella imageshashtags

con una relazione molti a molti. Un'immagine può avere molti tag hash e un hashtag può avere molte immagini.

Che tipo di approccio è adatto a mongo? Dalla lettura di q & a in questo modo: link

Vedo che posso implementare un documento secondario nel documento immagine con i tag. È efficiente per la ricerca e il recupero?

Potrei quindi utilizzare link - ridimensionare la mappa?

Quindi finisci con:

raccolta di immagini con tag sottodocumento tag collection

  • documento di immagini con tag documento secondario con tag estratti e aggiunti ad esso quando l'immagine viene creata e nuovo tag aggiunto alla raccolta se non è già presente (cioè i tag devono essere univoci)

crea anche il tag nella raccolta di tag ed esegui il map reduction.

Questo suono? Sto capendo le cose correttamente ed è il mio approccio ragionevole?

    
posta Dave 16.03.2013 - 04:41
fonte

2 risposte

3

Memorizza hashtag in un array all'interno di un documento.

Questo è il vantaggio di avere documenti: puoi semplicemente annidarli. E, in questo caso particolare, è banale:

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

(Ho aggiunto alcuni tag "sinonimi", questo può essere fatto automaticamente cercando un altro documento.)

Questa è la soluzione più naturale per il database orientato ai documenti:

  • La ricerca di documenti con hashtag è banale se si aggiunge un indice, così come l'inserimento, l'aggiornamento e l'eliminazione di hashtag su documenti casuali è anche banale
  • L'inserimento massiccio, l'aggiornamento e l'eliminazione sono un po 'complicati, perché probabilmente vorrai dividere tali operazioni in più "lotti", ma è comunque gestibile e non è difficile da implementare
  • Le aggregazioni complesse possono essere eseguite con la pipeline di aggregazione standard o con la ridondanza della mappa

D'altra parte, se si utilizza lo stile relazionale, si avrà un grosso problema quando si reinventa una percentuale di SQL% co_de all'interno del codice dell'applicazione. Questo è uno dei più comuni anti-pattern dell'utilizzo di MongoDB (e simili). Ecco uno pseudocodice molto tipico:

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

Questo è inefficiente, non scalabile e stai semplicemente reinventando una ruota. Usando questo, probabilmente finirai con la complessità di JOIN a causa dei loop all'interno del tuo codice. Se invece scegliessi SQL con chiavi esterne, avresti qualcosa come O(N*M) o anche O(N*log(M)) .

Non ci sono tabelle (relazioni) e chiavi esterne in MongoDB . Non inventarli, per favore. Usa SQL, se necessario. In effetti, consiglio vivamente di usare SQL al posto di MongoDB, a meno che i dati veramente siano costituiti da documenti.

Esempi tipici di documenti sono configurazioni, moduli e forse sessioni utente. Quelle in genere non si adattano bene alle tabelle a causa della struttura "casuale".

    
risposta data 14.11.2015 - 21:40
fonte
-1

Vorrei creare due tabelle. MongoDB è molto flessibile. Dico solo due tabelle anziché una tabella con i due campi "immagine" e "matrice di tag hash", perché ciò renderebbe più difficile la ricerca di tag hash.

Dovresti anche usare mangusta per connetterti al tuo database, è facile e flessibile rispetto all'inserimento diretto in MongoDB.

Le due tabelle dovrebbero essere:

  1. un campo, solo immagini, (mongo crea automaticamente un ID univoco per ogni voce (_id))

  2. Un database con due campi, "stringhe di tag #hash" e "un array di identificatori univoci corrispondenti alle immagini nella tabella delle immagini.

Dopo aver ricevuto la tua immagine, analizza i tag hash e salva le stringhe in una variabile locale. Inserisci l'immagine nella prima tabella e restituisci l'identificatore univoco (_id) per l'immagine.

Esegui un upsert alla seconda tabella per ogni tag #hash e inseriscilo con un ID immagine (_id) a cui appartiene. [il campo ID immagine sarà un array] (upsert cercherà una corrispondenza _id e creerà un nuovo documento se non ne esiste uno. Richiede jquery.)

Raccomando questa struttura del database per due motivi principali:

  1. Memorizza solo una copia di ogni immagine.

  2. Ti ha impostato per effettuare facilmente le chiamate di query a determinati tag #hash.

Tutto ciò che occorre è interrogare la tabella hashtag e restituire la matrice di ID immagine, quindi scorrere l'array di Picture ID che effettuano chiamate alla tabella delle immagini. Fammi sapere se desideri qualche chiarimento con questo, a volte ho difficoltà a spiegarmi chiaramente.

    
risposta data 18.03.2013 - 22:16
fonte

Leggi altre domande sui tag