Türchen 11: Eine Collection filtern

Türchen 11 zeigt wie in Magento eine Sammlung von Models eines Typ geladen werden kann: Die Collection. Natürlich geht das Türchen noch einen Schritt weiter und erläutert die einzelnen Möglichkeiten zur Filterung.

Will man einfach mal eben so alle Produkte seines Webshops auslesen, kann man das über die Methode getCollection des Product-Models tun.

$productCollection = Mage::getModel('catalog/product')->getCollection();

Eine solche Product-Collection ist quasi eine Datenbank-Abfrage. Welches SQL nachher an den Datenbankserver abgesetzt wird kann man einfach mittels der Methode getSelect überprüfen.

echo ( $productCollection->getSelect() );

In diesem Fall ergibt das folgendes SQL

SELECT `e`.* FROM `catalog_product_entity` AS `e`

Nun wäre es ziemlich ziemlich langsam erst alle Produkte abzurufen um nur z.B. das Produkt mit dem Namen "Webguys" zuhalten. So ist es in Magento möglich einen Filter auf die Collection anzuwenden. Ein solcher Filter macht letztlich nichts anderes als das aus der Collection erzeugte SQL um eine WHERE-Anweisung zu erweitern.

$productCollection->addFieldToFilter('name', 'Webguys');
echo ( $productCollection->getSelect() );

Die Methode addFieldToFilter leistet hier gute arbeitet. Das erzeugte SQL sieht nun wie folgt aus:

SELECT `e`.*, `_table_name`.`value` AS `name`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_varchar` AS `_table_name`
ON (_table_name.entity_id = e.entity_id)
AND (_table_name.attribute_id='60') AND (_table_name.store_id=0)
WHERE (_table_name.value = 'Webguys')

Wie zu erkennen ist hat Magento hier, durch das wir das Attribute 'name' benötigen, sich automatisch darum gekümmert die benötigten Tabellen zu joinen.

Nachdem wir so die Auswahl der Produkte eingegrenzt haben können wir z.B. mittels Foreach auf die einzelnen Produkte zugreifen.

foreach( $productCollection AS $product ) {
    echo $product->getName();
}

Genauso einfach lässt sich zählen wie viele Produkte von unserer Eingrenzung betroffen sind:

var_dump( count( $productCollection ) );

Aber addFieldToFilter kann noch mehr..

Nun können wir genau den Wert eines Zelle vergleichen aber uns fehlen noch eine Reihe von Möglichkeiten z.B. nach kleiner-gleich filtern zu können.

$productCollection->addFieldToFilter('entity_id', array( 'lteq' => 25) );
echo ( $productCollection->getSelect() );

Wieder nutzen wir die bekannte addFieldtoFilter Funktion von Magento, nur das wir anstelle eines genauen Wertes ein Array mit weiteren Optionen übergeben. Die Optionen sind in der Methode _getConditionSql näher spezifiziert. Hier einige Beispiele:

Optionen von addFieldToFilter

  • array("from"=>$fromValue, "to"=>$toValue) Spalte >= $fromValue AND spalte <= $toValue
  • array("like"=>$likeValue) Spalte LIKE '$likeValue'
  • array("neq"=>$notEqualValue) Spalte != $notEqualValue
  • array("in"=>array($inValues)) Spalte IN ( $inValues )
  • array("nin"=>array($notInValues)) Spalte NOT IN ( $notInValues )

Übersicht einiger Optionen

Magento-Option SQL
eq =
neq !=
like LIKE
nlike NOT LIKE
in IN
nin NOT IN
is IS
notnull IS NOT NULL
null IS NULL
moreq >=
gt >
lt <
gteq >=
lteq <=

Oder-Verknüpfungen

Die Optionen lassen sich mitunter auch per Oder-Verknüpfen:
$productCollection->addFieldToFilter('entity_id', array( array( 'eq' => 22 ), array( 'gteq' => 25) ) );
echo ( $productCollection->getSelect() );
Was zu folgendem SQL führt:
SELECT `e`.* FROM `catalog_product_entity` AS `e`
WHERE (((e.entity_id = 22) or (e.entity_id >= 25)))
Viel Spaß damit :) Update: Im englischen Magento-Wiki gibt es ebenfalls einen Beitrag dazu: Using Collections in Magento


Ein Beitrag von Tobias Vogt
Tobias's avatar

Tobias Vogt arbeitet seit 2008 mit Magento und ist seit 2011 durch Magento zertifizierter Entwickler. Seit 2016 ist er Mitgründer und CTO bei der connect-io GmbH, einer Magento-Agentur mit Sitz im idyllischen Paderborn-Salzkotten. Er gehört zum Gründer-Team der Webguys und ist seit November 2011 Bachelor of Science (Wirtschaftsinformatik). Sie erreichen Ihn per E-Mail unter tobi@webguys.de.

Alle Beiträge von Tobias

Kommentare
Tobi am

Sehr schön erklärt. Zum Nachschlagen aber immer wider hilfreich. :-)

Danke und Gruß, Tobi

Matthias Kleine am

Bei dem notnull Filter funktioniert das übrigens folgendermaßen:

array('notnull' => true)

Florin P. am

schöne übersicht und klar struckturiert. danke dafür

Danilo am

Schöner Artikel, sehr gut erklärt. Vielen Dank dafür!

Up-Sell, Cross-Sell und Related-Product-Links | Magento eCommerce, Shop - webguys.de am

[...] Collections, die anhand von bestimmten Attributen gefiltert werden können. Einen Artikel über die grundlegende Benutzung von Collections hat Tobias Vogt bereits hier [...]

Tobias Vogt am

Aber gern :)

chrisi am

Danke für die ausführliche Beschreibung, Magento ist nicht immer leicht zu verstehen!

Michael am

Sehr schön und anschaulich erklärt! Thumbs up ;-) Viele Grüße aus dem verschneiten Ingolstadt Michael

Dein Kommentar