Ergebnis 1 bis 8 von 8

Thema: Blacklist mit SQL

  1. #1
    az_hf0 ist offline Neuer Benutzer
    Registriert seit
    15.06.2009
    Beiträge
    23

    Standard Blacklist mit SQL

    Hallo zusammen,

    ich habe ein kleines Problem, bei dem ich mich über eine Idee von Euch freuen würde. Es hört sich zwar auf den ersten Blick einfach an, scheint es doch in sich zu haben.

    Folgendes Szenario:
    Ich habe eine Liste an Tags, die ich meiner Anfrage übergeben möchte, z.B.
    - Jacke
    - Hose
    - Pullover
    - Shirt

    Diese Liste möchte ich mit einer Blacklist vergleichen, die in einer Tabelle abgelegt ist. In der Tabelle würde z.B. stehen:
    - Jac*
    - Ho?e
    - Pull*

    Der Vergleich soll mir dann entweder die erlaubten Tags zurückgeben (alternativ auch die verbotenen, dann muss man da halt noch mal drüberiterieren). Also in diesem Fall nur:
    - Shirt (darauf matched kein Blacklisteintrag)

    Der Punkt ist, dass ich gerne Wildcards unterstützen möchte. Wie würdet ihr das realisieren? Ich könnte natürlich eine Stored Procedure schreiben, die aus allen Wildcards einen regulären Ausdruck generiert, aber das erscheint mir auch nicht performant. Das muss doch einfacher gehen, oder?

    Würde mich freuen, wenn jemand eine kreative Idee hätte :-D

    Viele Grüße,
    az_hf0

    PS: In der Realität ist das eine Tagcloud mit gestemmten Begriffen aus dem Bereich Health Sciences, von denen manche irrelevant sind.

  2. #2
    Avatar von progs
    progs ist offline Super-Moderator
    Registriert seit
    26.11.2005
    Ort
    Kulmbach, Bayern, Germany, 108121049209415, Kulmbach
    Beiträge
    185

    Standard

    Grob gesagt würde ich das jetzt mal so versuchen:

    Code:
    SELECT taglist.tag FROM taglist LEFT JOIN blacklist ON taglist.tag = backlist.tag WHERE blacklist.tag IS NULL
    Alternativ würde es denk ich auch mit taglist NOT IN(SELECT * FROM blacklist)

  3. #3
    az_hf0 ist offline Neuer Benutzer
    Registriert seit
    15.06.2009
    Beiträge
    23

    Standard Wildcard

    Hallo Progs,

    das Matching über den Join würde mir die irrelevanten Tags so aber nicht entfernen, denn in der Blacklist-Tabelle sind ja Einträge mit Wildcards enthalten. Jemand noch eine Idee?

    Viele Grüße,
    az_hf0

  4. #4
    ads
    ads ist offline Super-Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    4.056

    Standard

    Du wirst um reguläre Ausdrücke nicht herumkommen.
    Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören

    Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

    PostgreSQL Service & Support

  5. #5
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von ads Beitrag anzeigen
    Du wirst um reguläre Ausdrücke nicht herumkommen.
    Um mal zu zeigen, wie es gehen könnte:

    Code:
    test=*# select * from sachen;
        s
    ----------
     jacke
     hose
     pullover
     shirt
    (4 Zeilen)
    
    Zeit: 0,190 ms
    test=*# select * from sachen_suche ;
       r
    --------
     jac.*
     ho.e
     pull.*
    (3 Zeilen)
    
    Zeit: 0,184 ms
    test=*# select a.* from sachen a left join sachen_suche b on (a.s ~ b.r) where b.r is null;
       s
    -------
     shirt
    (1 Zeile)
    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  6. #6
    az_hf0 ist offline Neuer Benutzer
    Registriert seit
    15.06.2009
    Beiträge
    23

    Standard Keine temporäre Tabelle

    Danke Andreas, das ist wirklich ein guter Tip. Genau so hatte ich mir das vorgestellt, mir ist nur der ~-Operator nicht mehr eingefallen.

    Ich würde das noch lieber realisieren, ohne meine paar Sucheinträge vorher in die Tabelle "sachen" zu schreiben zu müssen. In meinem Fall müsste "sachen" sonst wohl eine temporäre Tabelle sein, worunter die Performance vermutlich etwas leiden würde.

    Weißt du, ob man direkt in einem Aufruf eine Menge in Tabellenform ranjoinen kann, die man on-the-fly übergibt?

    Viele Grüße,
    az_hf0

  7. #7
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von az_hf0 Beitrag anzeigen
    Danke Andreas, das ist wirklich ein guter Tip. Genau so hatte ich mir das vorgestellt, mir ist nur der ~-Operator nicht mehr eingefallen.

    Ich würde das noch lieber realisieren, ohne meine paar Sucheinträge vorher in die Tabelle "sachen" zu schreiben zu müssen. In meinem Fall müsste "sachen" sonst wohl eine temporäre Tabelle sein, worunter die Performance vermutlich etwas leiden würde.

    Weißt du, ob man direkt in einem Aufruf eine Menge in Tabellenform ranjoinen kann, die man on-the-fly übergibt?

    Viele Grüße,
    az_hf0
    Vielleicht als ARRAY und daraus on-the-fly eine Tabelle machen.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  8. #8
    az_hf0 ist offline Neuer Benutzer
    Registriert seit
    15.06.2009
    Beiträge
    23

    Standard Lösung

    Ich habe jetzt den Tip von Andreas gut verwenden können und das Problem so gelöst:

    Code:
    CREATE TABLE literature_tagcloud_excludes
    (
      excluded_item_id serial NOT NULL,
      excluded_tag text NOT NULL,
      CONSTRAINT pkey_literature_tagcloud_excludes PRIMARY KEY (excluded_item_id),
      CONSTRAINT unique_literature_tagcloud_excludes_excluded_tag UNIQUE (excluded_tag)
    );
    Die Anfrage wird dann so zusammengebaut:

    Code:
    SELECT
            tag.*
    FROM 
            explode_array(
                    array['Hose', 'Pullover', 'Jacke', 'T-Shirt']
            ) AS tag
    LEFT JOIN 
            literature_tagcloud_excludes lte
    ON 
            (tag ~* lte.excluded_tag) 
    WHERE 
            lte.excluded_tag IS NULL;
    Dabei wird eine Funktion verwendet, die aus einem übergebenen Array eine joinbare Tabelle erzeugt.

    Code:
    CREATE OR REPLACE FUNCTION explode_array(in_array anyarray)
      RETURNS SETOF anyelement AS
    $BODY$
        SELECT ($1)[s] FROM generate_series(1, array_upper($1, 1)) AS s;
    $BODY$
      LANGUAGE 'sql' IMMUTABLE;
    Bei {"Hos*", "Pull*", "Ja.ke"} in der Tabelle literature_tagcloud_excludes liefert die Anfrage dann das Ergebnis "T-Shirt".

    Danke für Eure Hilfe,
    az_hf0

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum