2013-01-14 21 views
8

Ho bisogno di un sistema di ricerca basato su tag di JCR come Modeshape. Voglio cercare i nodi con alcuni tag. La domanda è che qual è il modo migliore per implementarlo?Modo migliore per implementare un sistema di ricerca basato su tag di JCR come Modeshape

  1. Aggiunta nuovo tipo di nodo e mixins per i tag quindi se questo è vero, dove posso definire il mio nome tag che è visibile agli utenti?
  2. Implementare una gerarchia di tag e farli riferimento ai miei nodi. quindi se questo è vero come posso fare riferimento a loro?
  3. Qualsiasi altro modo.

risposta

13

Esistono diversi modi per implementare i tag in JCR. Quale opzione scegli dipenderà dai bisogni delle tue applicazioni. Ecco quattro opzioni che conosco.

Opzione 1: Uso Mixin

Definire per ogni tag una definizione di tipo di nodo intermedia che è un mixin marcatore (non ha definizioni di proprietà o le definizioni di nodo figlio), registrazione in modo dinamico utilizzando il NodeTypeManager. Quindi quando vuoi "taggare" un nodo, aggiungi semplicemente a quel nodo il mixin che rappresenta il tag. Ogni nodo può avere più tag e puoi richiedere tutti i nodi che hanno un determinato tag.

(Nel resto di questa risposta, "Acme" viene utilizzato come uno spazio dei nomi generici. È necessario sostituire questo con un namespace adatta per la propria applicazione e l'organizzazione.)

Ad esempio, dato un tag "acme: tag1", si potrebbe trovare tutti i nodi che hanno questo tag con il semplice query:

SELECT * FROM [acme:tag1] 

lo svantaggio di questo approccio è che il mantenimento tag è ingombrante. La creazione di nuovi tag richiede la registrazione di nuovi tipi di nodi. Non puoi facilmente rinominare i tag, ma invece dovresti creare il mixin per il tag con il nuovo nome; trova tutti i nodi che hanno il mixin che rappresenta il vecchio tag, rimuove il vecchio mixin e ne aggiunge uno nuovo; e infine rimuovere la definizione del tipo di nodo per il vecchio tag (dopo che non è più utilizzato da nessuna parte). La rimozione dei vecchi tag avviene in modo simile. Un altro svantaggio è che non è facile associare metadati aggiuntivi (ad esempio, nome visualizzato) con un tag, poiché le proprietà extra non sono consentite sulle definizioni del tipo di nodo.

Questo approccio dovrebbe funzionare abbastanza bene.

Opzione 2: Utilizzare una tassonomia e riferimenti forti

In questo approccio, si potrebbe creare una semplice struttura di nodo in una zona del repository in cui è possibile creare un nodo per ogni tag (ad esempio, un tassonomia). Su questo nodo puoi impostare proprietà che descrivono il tag (ad esempio, nome visualizzato); queste proprietà possono essere modificate in qualsiasi momento (ad es. per rinominare il tag).

Quindi per "applicare" il tag a un nodo, è sufficiente creare una sorta di relazione con il tag. Un modo è quello di definire un tipo di nodo mixin che contiene una proprietà multivalore "acme: tags" di tipo REFERENCE. Quando vuoi applicare uno o più tag a un nodo, aggiungi semplicemente il mixin al nodo e imposta la proprietà "acme: tags" ai nodi tag.

Per trovare tutti i nodi di un determinato tag, è possibile chiamare "getReferences()" su un nodo di tag per trovare tutti i nodi che contengono un riferimento al nodo di tag.

Questo approccio ha il vantaggio che tutti i tag devono essere controllati/gestiti all'interno di una o più tassonomie (incluse forse tassonomie specifiche dell'utente). Tuttavia, ci sono anche alcuni svantaggi. Innanzitutto, le prestazioni delle proprietà REFERENCE potrebbero non essere eccezionali. Alcune implementazioni JCR scoraggiano l'uso di REFERENCES del tutto. ModeShape non lo fa, ma ModeShape potrebbe iniziare a degradare le prestazioni di REFERENCE quando ci sono molti nodi che contengono riferimenti allo stesso nodo (ad esempio, molti nodi con un singolo tag).

Opzione 3: Uso tassonomia e riferimenti deboli

Questa opzione è un ibrido simile al precedente, tranne che l'opzione 2 "Acme: tag" proprietà sarebbero WeakReference invece di riferimento. Dovresti comunque definire e gestire una o più tassonomie. Per trovare nodi con un determinato tag, non è possibile utilizzare il metodo "getReferences()" sul nodo tag (poiché non funzionano con le proprietà WEAKREFERENCE), ma è possibile farlo facilmente con una query:

SELECT * FROM [acme:taggable] AS taggable 
JOIN [acme:tag] AS tag ON taggable.[acme:tags] = tag.[jcr:uuid] 
AND LOCALNAME(tag) = 'tag1' 

Questo approccio si applica utilizzando una o più tassonomie, rende un po 'più facile controllare i tag, poiché devono esistere in una tassonomia prima che possano essere utilizzati. Rinominare e rimuovere è anche più facile. Per quanto riguarda le prestazioni, questo è migliore dell'approccio REFERENCE, poiché le proprietà di WEAKREFERENCE funzioneranno meglio con un gran numero di riferimenti, indipendentemente dal fatto che puntino tutti a un nodo oa molti.

Lo svantaggio è che è possibile rimuovere un tag anche se è ancora utilizzato, ma i nodi che contengono un WEAKREFERENCE per quel tag rimosso non saranno più validi. Questo può essere risolto con alcune convenzioni nella tua applicazione, o semplicemente usando i metadati sulla tassonomia per dire che un determinato tag è "deprecato" e non dovrebbe essere usato. (IMO, il secondo è in realtà un vantaggio di questo approccio.)

Questa opzione generalmente eseguire e vanno molto meglio rispetto all'opzione 2.

Opzione 4: Utilizzare le proprietà di stringa

Un altro approccio è semplicemente utilizzare una proprietà STRING per taggare ciascun nodo con il nome dei tag che devono essere applicati. Ad esempio, puoi definire un mixin (es. "Acme: taggable") che definisce una proprietà STRING multivalore e quando vuoi taggare un nodo aggiungi semplicemente il mixin (se non è già presente) e aggiungi il nome del tag come valore sulla proprietà STRING "acme: tags" (di nuovo, se non è già presente come valore).

Il vantaggio principale di questo approccio è che è molto semplice: stai semplicemente utilizzando i valori stringa sul nodo che deve essere taggato. Per trovare tutti i nodi che sono contrassegnati con un determinato tag (ad esempio, "Tag1"), è sufficiente emettere una query:

SELECT * 
FROM [acme:taggable] AS taggable 
WHERE taggable.[acme:tags] = 'tag1' 

gestione dei tag è semplice: non c'è nessuna possibilità di gestione. Se un tag deve essere rinominato, puoi rinominare i valori del tag. Se un tag deve essere cancellato (e rimosso dai nodi che sono taggati con esso), allora ciò può essere fatto rimuovendo i valori dalle proprietà "acme: tags" (magari in un lavoro in background).

Si noti che questo consente di utilizzare qualsiasi nome di tag e pertanto funziona meglio per i casi in cui i nomi dei tag non sono controllati affatto.Se si desidera controllare l'elenco di stringhe utilizzate come valori di tag, è sufficiente creare una tassonomia nel repository (come descritto nelle Opzioni 2 e 3 sopra) e fare in modo che l'applicazione limiti i valori a quelli della tassonomia. Puoi persino avere più tassonomie, alcune delle quali sono forse specifiche dell'utente. Ma questo approccio non ha lo stesso controllo delle Opzioni 2 o 3.

Questa opzione avrà un risultato leggermente migliore dell'opzione 3 (poiché le query sono più semplici), ma si ridimensionerà ugualmente.

+0

Una variante consiste nell'utilizzare le proprietà stringa che puntano a una tassonomia utilizzando percorsi di stringa, ad esempio memorizzare/etc/tag/nature/animals/lion per puntare a tale tag. È molto simile alla tua opzione 3 con riferimenti deboli - non ottieni il controllo dell'esistenza di un tag prima di impostarlo, ma dato che devi comunque gestire i riferimenti pendenti a livello di applicazione, i riferimenti deboli non fanno una differenza significativa la mia opinione. Questo è praticamente il modo in cui gestiamo i tag in CQ5, come descritto su http://dev.day.com/content/ddc/blog/2009/04/cq5tags.html –

+0

Il grosso svantaggio dell'opzione 4 è che non c'è un modo semplice per elencare tutti i tag. È giusto? – ovonel

+0

ModeShape offre la funzione 'DISTINCT' nelle query JCR-SQL2, quindi puoi fare ciò:' SELECT DISTINCT [acme: tags] FROM [acme: taggable] '. Naturalmente, le prestazioni di questa query dipenderanno probabilmente da molti fattori, tra cui il numero di nodi, i tipi di indici, ecc. Tuttavia, se hai spesso bisogno dell'elenco di tag, una delle opzioni che utilizza una tassonomia potrebbe essere migliore . –