Ankündigung

Einklappen
Keine Ankündigung bisher.

String-in-String-Suche mit Doctrine

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • String-in-String-Suche mit Doctrine

    Hallo miteinander,

    ich habe in einem privaten Projekt eine String-in-String-Suche mit Doctrine geschrieben, die soweit auch funktioniert bzw. meine Anforderungen erfüllt.

    Da man es bei der Arbeit mit Doctrine (bzw. dem QueryBuilder-Objekt) aber eigentlich vermeiden will, sich Query-Strings mit der Low-Level-API zusammen zu tackern und stattdessen eher die High-Level-API mit der Expr-Klasse benutzen sollte (die ich aber wiederum schlecht dokumentiert finde), wollte ich einmal in die Runde fragen, ob jemand von euch einen Ansatz hat, das Ganze eleganter oder sauberer zu lösen oder ob man das so wie unten zu sehen machen kann.

    Hier findet ihr daher den entsprechenden Code aus einer Methode eines meiner Repositories:

    PHP-Code:
    $tags $article->getTagsArray();
    $queryString '';

    $qb $this->createQueryBuilder('a')
                 ->
    distinct()
                 ->
    where('a.id != :id')
                 ->
    setParameter('id'$article->getId())
                 ->
    andWhere('a.articleType = :articleType')
                 ->
    setParameter('articleType'$article->getArticleType());

    for (
    $i 0$i count($tags); $i++) {

        
    $queryString .= 'LOCATE(:tag' $i ', a.tags) > 0';
        
    $qb->setParameter('tag' $i$tags[$i]);

        if (
    $i count($tags)) {

            
    $queryString .= ' OR ';
        }
    }

    return 
    $qb->andWhere($queryString)
                 ->
    andWhere('a.active = true')
                 ->
    addOrderBy('a.id''DESC')
                 ->
    setMaxResults(5)
                 ->
    getQuery()
                 ->
    getResult(); 


  • #2
    Bring das Datenbankdesign in Normalform und du hast eine saubere Abfrage (JOIN und im WHERE ein IN).
    PHP-Code:
    ...->andWhere($qb->expr()->in('x.tags'':tags'))
                  ->
    setParameter('tags'$tags); 
    Damit gehst du auch Problemen aus den weg wie "Auto", "Autobahn". Bei deinem Ansatz matcht Auto auch Autobahn.

    Kommentar


    • #3
      Vielen Dank für deine Antwort, dieser Ansatz macht natürlich Sinn - Normalisierung ist mir natürlich auch ein Begriff.

      Ich habe meinen Ansatz jedoch gewählt, da die Datensätze matchen sollen, sobald eines der n Tags eines Artikels in den n Tags des anderen Artikels vorkommt.

      Wenn ich micht nicht täusche matcht dein Ansatz jedoch nur wenn alle n Tags beider Artikel deckungsgleich sind, oder?

      Kommentar


      • #4
        Nein, das ist eine ODER Verknüpfung. Der umgedrehte Fall wäre in der Normalform sogar relativ aufwendig.

        Kommentar

        Lädt...
        X