Eins-zu-viele-Filterung in der Mediendatenbank

Mit pms-mlx arbeite ich seit einiger time an einer Medienbibliothek, um die functionen des ps3-Medienservers zu erweitern, und habe erst kürzlich einen wichtigen Teil meines Konzepts entdeckt. Es ist nicht möglich, zu filtern, wenn mehr als eine Eins-zu-viele-Eigenschaft verwendet wird.

Bevor ich Fragen stelle, sollte ich erklären, wie es funktioniert.
Hier ist die DB-Struktur für den relevanten Teil des Codes. h2 wird verwendet.
DB-Schema-Video
Jedes Video ist eine file und hat 0-n der angehängten properties.

Sobald einige Videos gespeichert wurden, können Sie sie in Ordnern anzeigen und abspielen, in denen nur eine Teilmenge aller Einträge angezeigt wird, indem Sie Bedingungen festlegen. Hier ist ein Beispiel:
pms-mlx-Bedingungsbeispiel

Um die gewünschten fileen abzurufen, wird die Abfrage wie folgt aufgebaut

SELECT <all_properties> FROM FILE, VIDEO LEFT JOIN VIDEOAUDIO ON VIDEO.FILEID = VIDEOAUDIO.FILEID LEFT JOIN SUBTITLES ON VIDEO.FILEID = SUBTITLES.FILEID LEFT JOIN FILETAGS ON VIDEO.FILEID = FILETAGS.FILEID LEFT JOIN FILEPLAYS ON VIDEO.FILEID = FILEPLAYS.FILEID WHERE <whereClause> ORDER BY <orderBy> 

Nur die Wo und Reihenfolge nach Teilen sind dynamisch. Die where-Klausel wird erstellt, indem die Bedingungsnamen (c1, c2) durch die entsprechenden SQL-Gegenstücke ersetzt werden. Für das obige Beispiel wird diese Where-Klausel generiert:

 WHERE VIDEO.FILEID = FILE.ID AND ((VIDEO.NAME LIKE 'A%' OR VIDEO.NAME LIKE 'B%') AND FILE.DATEINSERTEDDB > '2011-09-28 18:48:43') 

Bei der Abfrage werden für jede file viele Zeilen zurückgegeben. Beim Durchlaufen der Ergebnisse werden die 'neuen' data, die in der Rohdatei enthalten sind, hinzugefügt, um das object zu erstellen.

Wenn der Filter eine Eins-zu-viele-Bedingung enthält, wird die Abfrage in zwei Schritten ausgeführt. Zuerst werden die IDs aller Videos abgerufen und dann die data geladen.

Was ich bis jetzt vermisst habe, ist, dass, wenn zB zwei file-Tags vorhanden sind und beide erfüllt sein sollten, nichts mehr funktioniert. Wenn Sie den Filter einstellen:
nicht funktionierendes Filterbeispiel
Daraus ergibt sich folgende where-Klausel:

 WHERE VIDEO.FILEID = FILE.ID AND ((VIDEO.FILEID = FILETAGS.FILEID AND FILETAGS.KEY = 'Actor' AND FILETAGS.VALUE LIKE 'A%') AND (VIDEO.FILEID = FILETAGS.FILEID AND FILETAGS.KEY = 'Actor' AND FILETAGS.VALUE LIKE 'B%')) 

was nie erreicht wird, da eine einzelne Zeile nur ein Schlüssel- und ein Wertfeld enthält.

Wäre es möglich, eine Abfrage zu erstellen, bei der alle data für ein einzelnes Video in einer Zeile enthalten wären? Oder replace Sie die generierte SQL-Bedingung durch etwas anderes?
Ich bin kein db Experte und würde gerne von jemandem da sein, der eine gute Idee hat 🙂

Der Code zum Generieren der Where-Klausel befindet sich in der Methode formatFilter in Zeile 445 von DBFileInfo.java . Das Laden der data erfolgt in Zeile 189 von DBVideoFileInfo.java, wenn jemand den Code sehen möchte .

Solutions Collecting From Web of "Eins-zu-viele-Filterung in der Mediendatenbank"

Ihre komplexen Tabellenbeziehungen sind für ein einfaches Beispiel des Problems etwas verwirrend, aber können Sie nicht einfach eine Reihe von Kriterien aufbuild?

 WHERE FILEID IN (SELECT [all files that have brad]) AND FILEID IN (SELECT [all files that have angelina]) AND FILEID IN (SELECT [all files that have elvis]) 

Sicher würde das nur fileen zurückgeben, in denen Brad, Angelina und Elvis sind? (Wahrscheinlich nicht viele).

Sie müssen Ihre GUI verwenden, damit der Benutzer angeben kann, ob der Filter als AND oder OR funktionieren soll. In deinem letzten Fall brauchst du natürlich OR . Ihre WHERE Klausel wird also so aussehen:

 WHERE VIDEO.FILEID = FILE.ID AND VIDEO.FILEID = FILETAGS.FILEID AND FILETAGS.KEY = 'Actor' AND (FILETAGS.VALUE LIKE 'A%' OR FILETAGS.VALUE LIKE 'B%') 

Beachten Sie, dass die Wiederholung gemeinsamer Bedingungen eliminiert wird und das gemeinsame Stück auf die obere Ebene von WHERE verschoben wird.

Ich denke, dass Sie sowohl Ihre GUI und SQL-Generator dafür benötigen.


UPDATE Wenn Sie sowohl 'A%' als auch 'B%' in Ergebnisfilmen benötigen, müssen Sie die WHERE Klausel ändern

 WHERE VIDEO.FILEID = FILE.ID AND EXISTS -- look if movie have 'A%' actor (SELECT 1 FROM FILETAGS WHERE AND VIDEO.FILEID = FILETAGS.FILEID AND FILETAGS.KEY = 'Actor' AND FILETAGS.VALUE LIKE 'A%') AND EXISTS -- look if the same movie have 'B%' actor (SELECT 1 FROM FILETAGS WHERE AND VIDEO.FILEID = FILETAGS.FILEID AND FILETAGS.KEY = 'Actor' AND FILETAGS.VALUE LIKE 'B%') 

Wie auch immer, dies sind nur Beispiele, wie Abfragen aussehen können, abhängig von der Eingabe des Benutzers. Die ursprüngliche Frage, wie ich sie verstanden habe, war eine bestimmte Situation, keine allgemeine Lösung. Im Allgemeinen muss Ihre Anwendung im Allgemeinen unterschiedliche Bedingungen verwenden, die die Benutzerauswahl in der Benutzeroberfläche widerspiegeln.

Für den allgemeinen Fall benötigen Sie eine Form von "SQL Builder", wie diese . Oder Sie möchten ein ORM-Tool verwenden, das SQL halbautomatisch für Sie erstellt. Aber wenn Sie SQL nicht gut beherrschen, rate ich Ihnen, mit dem SQL-Builder zu beginnen, um SQL-Kenntnisse auf niedriger Ebene zu erhalten. Die Verwendung von ORM erfordert ein gutes Verständnis von SQL und verwandten Themen.