Aquí está mi código:
$catIds = array(7,8,9);
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect("*");
->addAttributeToFilter('category_ids', array('nin' => $catIds));
Quiero obtener todos los productos que no están en la lista de identificadores de categoría, pero mi código no dio el resultado esperado. Por favor muéstrame el camino, gracias.
magento-1
filter
product-collection
category-products
Lan Nguyen
fuente
fuente
Respuestas:
Debe unirse a la tabla que contiene las relaciones categoría / producto.
Una variación de la colección que uso para encontrar todos los productos EN una lista de categorías debería ser la solución para usted:
(no probado, pero debería llevarte por el camino correcto)
ref: http://www.proxiblue.com.au/blog/Collection_of_products_in_all_child_categories/
fuente
El siguiente código funcionará para usted:
fuente
He encontrado una forma algo mejor de hacerlo, usando un anti-join (Magento 1.9).
Beneficios de este enfoque
El beneficio de esto sobre la respuesta original es que no obtendrá falsos positivos, y como resultado es más rápido y menos propenso a errores. Por ejemplo, suponga que tiene un solo producto:
Desea "encontrar todos los productos que no están en él
category 3
y luego agregarlos acategory 3
" . Entonces ejecuta unaNOT IN
consulta, y devolverá dos filas(name | category_id)
:No es gran cosa, Magento solo devolverá el primer resultado y luego lo agregará. Excepto ! La segunda vez que se ejecuta esta consulta, tiene los mismos resultados:
Y Magento te dirá que todavía no le has agregado esta camisa
category 3
. Esto se debe a que cuando un producto pertenece a varias categorías, tendrá varias filas en la tabla "catalog_product_entity" . Y entonces aLEFT JOIN
devolverá múltiples resultados.Esto no es deseable porque
in_array($categoryThree, $product->getCategories())
), lo que significa que pasará a través de resultados innecesarios. Esto hará que su script / código sea más lento, especialmente con grandes inventarios.Solución
La consulta SQL generada se verá así:
Explicación:
Dadas las tablas de relación producto y producto <=> categoría:
catalog_product_entity
+-----------+ | ENTITY_ID | +-----------+ | 423 | | 424 | | 425 | +-----------+
catalog_category_product
+-------------+------------+ | CATEGORY_ID | PRODUCT_ID | +-------------+------------+ | 3 | 423 | | 123 | 424 | | 3 | 425 | +-------------+------------+
Su consulta dice: " deme todas las filas en " catalog_product_entity " y péguelo en la columna" category_id "de " catalog_category_product " . Luego, solo deme las filas que category_id = 124" .
Debido a que es una combinación izquierda, siempre tendrá las filas de "catalog_product_entity" . Para cualquier fila que no pueda coincidir, será
NULL
:Resultado
+-------------+-------------+ | ENTITY_ID | CATEGORY_ID | +-------------+-------------+ | 423 | NULL | | 424 | 123 | | 425 | NULL | +-------------+-------------+
A partir de ahí, la consulta dice: "ok, ahora dame todo donde el category_id es NULL" .
fuente
No es tan fácil como parece.
Aquí está la opción basada en GROUP_CONCAT, ya que su límite predeterminado (1024 pero podría aumentarse, por supuesto) debería estar bien con los ID de categoría de producto separados por comas.
Además (si no le gusta GROUP_CONCAT) puede usar WHERE product_id NOT IN en una subconsulta de un ID de producto que en realidad está en las categorías que necesita excluir (no proporcionarlo aquí).
El enfoque anti-unión de otra respuesta también funcionará. Pero en este caso no puede agregar fácilmente condiciones adicionales.
fuente