mi hanno taggato oggetti in un repository Jackrabbit (in realtà di Adobe/Giorno CQ CRX, ma penso che questo è il codice Jackrabbit):ricerche Jackrabbit attraverso nodi uniti
- patrimoniale: tag = A, B
- bambino di dati di attività 1: tag = a, C, E
- dati figlio di attività 2: tag = D, E
voglio q uery contro l'unione di insieme del bene genitore di tag e un bambino, vale a dire "BC" sarebbe partita bene perché abbiamo quelli del genitore e nel bambino 1, ma "CD" non sarebbe partita, perché non c'è nessuna combinazione di genitore e uno figlio che corrisponde a quello perché C e D sono suddivisi su nodi dati figlio separati.
C'è un modo per fare questo in Jackrabbit? Possiamo scrivere una query XPath
\\element(*, dam:Asset)[(@tags = 'C' or *\@tags='C')
and (@tags = 'D' or *\@tags='D')]
ma che non funziona perché XPath non sembra garantire che il *
uniti asset secondari sono gli stessi, vale a dire questo significa "ogni bambino ha C/D" e così abbinerà il mio bene perché 1+ bambini hanno un C e 1 + i bambini hanno una D. invece ho potuto usare JCR-SQL2
SELECT * FROM dam:Asset as asset
LEFT OUTER JOIN nt:unstructured as child ON ISCHILDNODE(child,asset)
WHERE (asset.tags = 'C' or child.tags = 'C')
AND (asset.tags = 'D' or child.tags = 'D')
ma non c'è SELECT DISTINCT
in JCR-SQL2: se invece la ricerca di "BE" Otterrò questa risorsa restituita due volte perché corrisponde sia a asset + child1 che a asset + child2.
Potrei postelaborare sia il risultato della query in Java, ovvero filtrare le corrispondenze false-positive per il primo caso o filtrare i risultati duplicati per il secondo caso, ma sono nervoso su come ciò potrebbe influire sulle prestazioni del paging: avrei bisogno per eseguire la scansione di più nodi del necessario per eliminare i nodi danneggiati, e avrei bisogno di scansionare il lotto per calcolare la dimensione del risultato corretta per il paging. Questo dovrebbe essere più conveniente per il secondo caso SQL2 perché se la mia ricerca è ordinato posso individuare i duplicati in base solo al percorso del nodo e tutti i duplicati saranno consecutivi, in modo da poter trovare la pena di un dato pagina di dati con scansione a buon mercato solo si spera senza leggere l'intero nodo per ogni risultato, ma non conosco il costo di scansionare tutti i risultati per il conteggio delle pagine anche per il caso di solo percorso semplice.
Ancora un'altra opzione che abbiamo considerato è denormalizzare i tag in un unico nodo. In questo caso, per mantenere la ricerca accurata, ciò dovrebbe significare creare un nuovo attributo combined_tags in ogni nodo figlio ed eseguire tutte le ricerche solo sull'insieme di nodi figlio. Tuttavia questo soffre ancora del problema distinto se dovessimo abbinare due nodi figlio sotto la stessa risorsa.
Grazie per eventuali suggerimenti. Questo è già un grande esempio e sarà necessario ridimensionarlo ulteriormente. Ho visto altre domande che dicono ModeShape è un'implementazione di JCR che ha SELECT DISTINCT
ma penso che il passaggio a ModeShape solo per questo avrebbe dovuto essere l'ultima risorsa, se davvero è possibile ospitare CQ su ModeShape.
Un'idea che è venuta in mente è ora quello di calcolare ogni unione dei tag attivi e tag di livello inferiore e combinare i tag in una singola stringa quindi scrivere ogni valore come una proprietà multivalore del bene, vale a direasset + child1 = "A B C E" e asset + child2 = "A B D E", quindi otteniamo
- asset: tag = A, B; tagUnions = "ABCE", "ABDE"
Finché si definisce un ordine fisso per combinare i tag in una stringa (ad esempio alfabetico) possiamo la ricerca di qualsiasi combinazione usando tagUnions LIKE '%B%C%'
(tranne userei delimitatori appropriati tra tag nel caso reale). Anche se funzionerà il più possibile, non mi piace molto: ci sono potenzialmente molti numeri di tag per risorsa + figlio, tutti con nomi più lunghi di singole lettere, il che significa che ci ritroveremo con lunghe stringhe che eseguono query LIKE
su tutti di loro che probabilmente non possono essere indicizzati in modo efficiente.
Un altro modo per fare questo è creare una maschera di bit: definire A = 1, B = 2 ecc. Quindi memorizzare una serie di numeri interi multivalore e quindi eseguire un confronto bit a bit. Tuttavia questo è probabilmente limitato a 64 tag diversi e poiché abbiamo 1.000+ non credo che possiamo farlo - anche se JCR supporta operazioni bit a bit, cosa che mi aspetterei che non lo fosse.
Quindi sono ancora alla ricerca di una soluzione pulita simile a un database per questo. Ti sei perso la taglia che ho messo, ma ci sono ancora zecche, voti e gratitudine per qualsiasi aiuto.
Grazie. Non è in realtà un 'UNION' SQL di cui ho bisogno in termini di unione di set su due query, ma sto calcolando una corrispondenza con un'unione logica di due proprietà attraverso nodi diversi quindi è un 'JOIN' e' SELECT DISTINCT' SQL che Ho bisogno.La soluzione che colleghi - ordina e rimuovi duplicati consecutivi - è una delle idee che ho menzionato nel paragrafo sui risultati di post-elaborazione, e il problema con questo è il paging giusto: avrei bisogno di scansionare tutti i record fino all'attuale pagina per capire dove inizia effettivamente la pagina e scansionare tutto per ottenere il numero esatto di pagine totali. – Rup
... e il sistema con cui lavoro ha milioni di risorse, quindi non sono inediti oltre 10.000 risultati di una query semplice - Non posso presumere di avere un piccolo numero di risultati come dice il ragazzo che ha quella soluzione collegata. Ho bisogno di un ordinamento basato sul database al fine di ottenere un efficiente paging, penso. In ogni caso i documenti di Jackrabbit consigliano comunque di utilizzare un 'ORDER BY' poiché l'ordine predefinito JCR (a meno che non sia disabilitato in repository.xml) è potenzialmente costoso da calcolare. – Rup
@Rup Grazie per l'aggiornamento. Come accennato, la post-elaborazione dei risultati in Java è possibile, ma può essere potenzialmente costosa quando si attraversano nodi aggiuntivi che altrimenti si sono già visitati. Quindi, si tratta di una traversata efficiente attraverso la struttura dei dati. Hmn. Dovrò guardarlo più tardi e tornare da te. :) – MrGomez