Hier ist mein Code:
$catIds = array(7,8,9);
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect("*");
->addAttributeToFilter('category_ids', array('nin' => $catIds));
Ich möchte alle Produkte erhalten, die nicht in der Liste der Kategorie-IDs enthalten sind, aber mein Code hat nicht das erwartete Ergebnis geliefert. Bitte zeig mir den Weg, danke.
magento-1
filter
product-collection
category-products
Lan Nguyen
quelle
quelle
Antworten:
Sie müssen der Tabelle beitreten, die die Kategorie- / Produktbeziehungen enthält.
Eine Variation der Sammlung, mit der ich alle Produkte in einer Liste von Kategorien finde, sollte den Trick für Sie tun:
(ungetestet, sollte dich aber auf den richtigen Weg bringen)
ref: http://www.proxiblue.com.au/blog/Collection_of_products_in_all_child_categories/
quelle
Der folgende Code funktioniert für Sie:
quelle
Ich habe einen etwas besseren Weg gefunden, dies mit einem Anti-Join (Magento 1.9) zu tun.
Vorteile dieses Ansatzes
Dies hat gegenüber der ursprünglichen Antwort den Vorteil, dass Sie keine Fehlalarme erhalten und dadurch schneller und weniger fehleranfällig sind. Angenommen, Sie haben ein einzelnes Produkt:
Sie möchten "alle Produkte finden, die nicht in sind
category 3
, und sie dann hinzufügencategory 3
" . Sie führen also eineNOT IN
Abfrage aus und es werden zwei Zeilen zurückgegeben(name | category_id)
:Keine große Sache, Magento gibt immer noch nur das erste Ergebnis zurück, und dann fügen Sie es hinzu. Außer ! Wenn diese Abfrage zum zweiten Mal ausgeführt wird, erhalten Sie dieselben Ergebnisse:
Und Magento wird Ihnen sagen, dass Sie dieses Shirt noch nicht hinzugefügt haben
category 3
. Dies liegt daran, dass ein Produkt, das zu mehreren Kategorien gehört, mehrere Zeilen in der Tabelle "catalog_product_entity" enthält . Und soLEFT JOIN
wird a mehrere Ergebnisse zurückgeben.Dies ist unerwünscht, weil
in_array($categoryThree, $product->getCategories())
), was bedeutet, dass Sie unnötige Ergebnisse durchlaufen. Dies verlangsamt Ihr Skript / Ihren Code, insbesondere bei großen Lagerbeständen.Lösung
Die generierte SQL-Abfrage sieht folgendermaßen aus:
Erläuterung:
In Anbetracht der Beziehungstabellen für Produkt und Produktkategorie <=>:
catalog_product_entity
+-----------+ | ENTITY_ID | +-----------+ | 423 | | 424 | | 425 | +-----------+
catalog_category_product
+-------------+------------+ | CATEGORY_ID | PRODUCT_ID | +-------------+------------+ | 3 | 423 | | 123 | 424 | | 3 | 425 | +-------------+------------+
Ihre Abfrage lautet: "Geben Sie mir alle Zeilen in " catalog_product_entity " und fügen Sie sie in die Spalte" category_id "von " catalog_category_product "ein . Geben Sie mir dann einfach die Zeilen" category_id = 124 " .
Da es sich um eine Linksverknüpfung handelt, enthält sie immer die Zeilen von "catalog_product_entity" . Für alle Zeilen, die nicht abgeglichen werden können, gilt Folgendes
NULL
:Ergebnis
+-------------+-------------+ | ENTITY_ID | CATEGORY_ID | +-------------+-------------+ | 423 | NULL | | 424 | 123 | | 425 | NULL | +-------------+-------------+
Von dort sagt die Abfrage dann: "OK, jetzt gib mir alles, wo die category_id NULL ist" .
quelle
Nicht so einfach wie es aussehen mag.
Hier ist die GROUP_CONCAT-basierte Option, da das Standardlimit (1024, könnte aber natürlich erhöht werden) mit durch Kommas getrennten Produktkategorie-IDs in Ordnung sein sollte.
Außerdem (wenn Sie GROUP_CONCAT nicht mögen) können Sie WHERE product_id NOT IN in einer Unterabfrage einer Produkt-ID verwenden. IDs sind tatsächlich IN Kategorien, die Sie ausschließen müssen (hier nicht angeben).
Der Anti-Join-Ansatz einer anderen Antwort funktioniert ebenfalls. In diesem Fall können Sie jedoch nicht einfach zusätzliche Bedingungen hinzufügen.
quelle