{"id":145,"date":"2013-04-20T22:18:45","date_gmt":"2013-04-20T20:18:45","guid":{"rendered":"http:\/\/www.zellot.at\/blogs\/?p=145"},"modified":"2013-04-20T22:18:45","modified_gmt":"2013-04-20T20:18:45","slug":"doctrine2-subquerys-und-der-identity-helfer","status":"publish","type":"post","link":"https:\/\/www.zellot.at\/blogs\/2013\/04\/20\/doctrine2-subquerys-und-der-identity-helfer\/","title":{"rendered":"Doctrine2 Subquerys und der IDENTITY Helfer"},"content":{"rendered":"<p>Vor allem bei Suchquerys kommt man oft nicht an Subquerys vorbei. Konkretes beispielswei\u00dfe ist hier die Suche nach Eintr\u00e4gen mit gewissen Tags im AAUShare System. Es gibt hier das Post Entity mit den Mappings zu den Tags, bzw PostTags(Mapping zwischen Tags und Posts). Um hier z.B. alle Posts zu erhalten die mit einen Tag besitzen ist noch recht unkompliziert, m\u00f6chte man jedoch nur Posts mit z.B. den Tags Informatik und ESOP so wird die Query schon komplizierter. Ich habe dazu folgende Methode implementiert:<br \/>\n<pre><code class=\"preserve-code-formatting\">\npublic function findByTagTitles(array $tags, $additive){\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tagtsrings = &#039;&#039;;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$logicalop = &#039;OR&#039;;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($additive == true){\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$logicalop = &#039;AND&#039;;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/create query statement ors and ands\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for($i=0; $i&lt;sizeof($tags); $i++){\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tagtsrings .= &#039; p.id IN (SELECT IDENTITY(pt&#039;.$i.&#039;.post) FROM AAUShare\\Entity\\PostTag pt&#039;.$i.&#039; JOIN pt&#039;.$i.&#039;.tag t&#039;.$i.&#039; WITH t&#039;.$i.&#039;.title LIKE :tag&#039;.$i.&#039;)&#039;;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(($i+1) &lt; sizeof($tags)){ \/\/last and or or\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tagtsrings .=&#039; &#039;.$logicalop;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(sizeof($tags)==0){\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tagtsrings.=&#039;1&#039;;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$querystring = &#039;SELECT p FROM AAUShare\\Entity\\Post p WHERE&#039;.$tagtsrings;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$query = $this-&gt;getEntityManager()-&gt;createQuery($querystring);\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/bind\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for($i=0; $i&lt;sizeof($tags); $i++){\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$query-&gt;setParameter(&#039;tag&#039;.$i, $tags[$i]);\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/do query\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $query-&gt;getResult();\n&nbsp;&nbsp;&nbsp;&nbsp;}\n<\/code><\/pre><\/p>\n<p>Hier wird ein Array mit Tags \u00fcbergeben, nach welchen gesucht wird, der zweite Parameter bestimmt ob die Tags mit &#8222;AND&#8220; oder mit &#8222;OR&#8220; verkn\u00fcpft werden. Interessant sind hierbei vor allem die for-Schleifen. In der ersten werden die Tags in Subquerys gepackt und gepr\u00fcft ob der Post in der Menge der zur\u00fcckgelieferten postids vorhanden ist. Wichtig ist hierbuach der <strong>IDENTITY<\/strong> Befehl f\u00fcr Doctrine2, damit wird auf den Foreign Key der OneToMany Relation in PostTag zugegriffen. Au\u00dferdem werden die Subquerys durchnummeriert und auch damit die Parameter<\/p>\n<p>\n In der zweiten for-Schleife werden die durchnummerierten Query Parameter noch mit den Werten aus den Tags verkn\u00fcpft.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vor allem bei Suchquerys kommt man oft nicht an Subquerys vorbei. Konkretes beispielswei\u00dfe ist hier die Suche nach Eintr\u00e4gen mit gewissen Tags im AAUShare System. Es gibt hier das Post Entity mit den Mappings zu den Tags, bzw PostTags(Mapping zwischen Tags und Posts). Um hier z.B. alle Posts zu erhalten die mit einen Tag besitzen [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,3],"tags":[21,28,31,30,29],"class_list":["post-145","post","type-post","status-publish","format-standard","hentry","category-doctrine-2","category-php","tag-doctrine2","tag-identity","tag-komplexe-query","tag-parameter","tag-subquery"],"_links":{"self":[{"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/posts\/145","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/comments?post=145"}],"version-history":[{"count":2,"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/posts\/145\/revisions"}],"predecessor-version":[{"id":147,"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/posts\/145\/revisions\/147"}],"wp:attachment":[{"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/media?parent=145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/categories?post=145"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zellot.at\/blogs\/wp-json\/wp\/v2\/tags?post=145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}