Aqui está o meu código:
$catIds = array(7,8,9);
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect("*");
->addAttributeToFilter('category_ids', array('nin' => $catIds));
Desejo que todos os produtos não estejam na lista de códigos de categoria, mas meu código não forneceu o resultado esperado. Por favor, mostre-me o caminho, obrigado.
magento-1
filter
product-collection
category-products
Lan Nguyen
fonte
fonte
Respostas:
Você precisa ingressar na tabela que contém as relações categoria / produto.
Uma variação da coleção que eu uso para encontrar todos os produtos em uma lista de categorias deve fazer o truque para você:
(não testado, mas deve colocá-lo no caminho certo)
ref: http://www.proxiblue.com.au/blog/Collection_of_products_in_all_child_categories/
fonte
O código a seguir funcionará para você:
fonte
Eu encontrei uma maneira um pouco melhor de fazer isso, usando um anti-join (Magento 1.9).
Benefícios desta abordagem
O benefício disso em relação à resposta original é que você não obterá falsos positivos e, como resultado, é mais rápido e menos propenso a erros. Por exemplo, suponha que você tenha um único produto:
Você deseja "encontrar todos os produtos que não estão dentro
category 3
e adicioná-los acategory 3
" . Então, você executa umaNOT IN
consulta e ela retornará duas linhas(name | category_id)
:Não é grande coisa, o Magento ainda retornará apenas o primeiro resultado e você o adicionará. Exceto ! Na segunda vez que essa consulta é executada, você tem os mesmos resultados:
E o Magento lhe dirá que você ainda não adicionou esta camisa
category 3
. Isso ocorre porque quando um produto pertence a várias categorias, ele tem várias linhas na tabela "catalog_product_entity" . E assim umLEFT JOIN
retornará vários resultados.Isso é indesejável porque
in_array($categoryThree, $product->getCategories())
), o que significa que você percorrerá resultados desnecessários. Isso tornará seu script / código mais lento, especialmente em grandes inventários.Solução
A consulta SQL gerada será semelhante a:
Explicação:
Dadas as tabelas de relacionamento de produto e categoria de produto <=>:
catalog_product_entity
+-----------+ | ENTITY_ID | +-----------+ | 423 | | 424 | | 425 | +-----------+
catalog_category_product
+-------------+------------+ | CATEGORY_ID | PRODUCT_ID | +-------------+------------+ | 3 | 423 | | 123 | 424 | | 3 | 425 | +-------------+------------+
Sua consulta está dizendo "dê-me todas as linhas em " catalog_product_entity " e cole na coluna" category_id "de " catalog_category_product " . Depois, basta me fornecer as linhas que category_id = 124" .
Por ser uma junção esquerda, ela sempre terá as linhas de "catalog_product_entity" . Para qualquer linha que não possa ser correspondida, será
NULL
:Resultado
+-------------+-------------+ | ENTITY_ID | CATEGORY_ID | +-------------+-------------+ | 423 | NULL | | 424 | 123 | | 425 | NULL | +-------------+-------------+
A partir daí, a consulta então diz: "ok, agora me dê tudo onde o category_id é NULL" .
fonte
Não é tão fácil quanto pode parecer.
Aqui está a opção baseada em GROUP_CONCAT, pois seu limite padrão (1024, mas pode ser aumentado, é claro) deve estar bem com os IDs de categoria de produto separados por vírgulas.
Além disso (se você não gosta de GROUP_CONCAT), pode usar WHERE product_id NOT IN em uma subconsulta de um ID de produto, na verdade, estão em categorias que você precisa excluir (não fornecendo aqui).
A abordagem anti-junção de outra resposta também funcionará. Mas, neste caso, você não pode adicionar facilmente condições adicionais.
fonte