বিভাগগুলিতে নয় কীভাবে পণ্যগুলি ফিল্টার করবেন?


10

আমার কোডটি এখানে:

$catIds = array(7,8,9);
$collection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect("*");
    ->addAttributeToFilter('category_ids', array('nin' => $catIds));

আমি বিভাগের আইডির তালিকায় না রেখে সমস্ত পণ্য পেতে চাই তবে আমার কোডটি প্রত্যাশিত ফলাফল দেয়নি। দয়া করে আমাকে উপায়টি দেখান, ধন্যবাদ


আপনি যে ফলাফলটি পেয়েছিলেন তার ফলাফল কী আশা করেছিলেন?
আহ্নবিজক্যাড

উত্তর:


16

বিভাগ / পণ্য সম্পর্ক ধারণ করে এমন টেবিলে আপনাকে যোগদান করতে হবে।

বিভাগগুলির একটি তালিকার মধ্যে সমস্ত পণ্য সন্ধান করার জন্য আমি সংগ্রহের ব্যবহারের বিভিন্নতাটি আপনার জন্য কৌশলটি করা উচিত:

(অনির্ধারিত, তবে আপনাকে সঠিক ট্র্যাকে উঠানো উচিত)

$productCollection = Mage::getResourceModel('catalog/product_collection')
    ->setStoreId(0)
    ->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
    ->addAttributeToFilter('category_id', array('nin' => $catIds))
    ->addAttributeToSelect('*');

$productCollection->getSelect()->group('product_id')->distinct(true);
$productCollection->load();

রেফ: http://www.proxiblue.com.au/blog/ Colલેક્___ প্রোডাক্টস_ইন_সাল_চাইল্ড_ বিভাগসমূহ /


1
কোনও পণ্য একাধিক বিভাগে প্রদর্শিত হলে এটি কাজ করে না। 'নিন' কেবল এই এক সারি বাদ দেয় না, তবে পণ্য আইডিটি অন্য বিভাগগুলির জন্য এখনও উপস্থিত হবে।
Greatwitenorth

হাই, কোডটি দাঁড়িয়েছে, এটি 100% কাজ করে। লিখিত কোডটি ভেরিয়েবল $ ক্যাটআইডসে প্রদত্ত বিভাগের তালিকা অনুযায়ী পণ্যটিকে বাদ দেবে। যদি পণ্যটি একাধিক বিভাগে উপস্থিত হয় এবং সেই বিভাগটি বাদ দেওয়ার তালিকায় অন্তর্ভুক্ত না হয় তবে ভাল, এটি উপস্থিত হবে। এরপরে দোষটি হ'ল আপনি সমস্ত বিভাগ বাদ দিচ্ছেন না। কোডটি যাদুকরভাবে (যেমনটি লিখিত আছে) জানে না পণ্যটি অন্যান্য বিভাগে প্রদর্শিত হয়>
ProxiBlue

আপনি যেমন পণ্য আইডিকে বাদ দিয়ে কোনও উপায় চাইছেন তার মতো আরও শোনান, যা আপনি উপরের কোডটি খুব সহজেই ফর্মটি অর্জন করতে পারেন। প্রথম টিপটি আইএন-এ পরিবর্তিত হবে, তারপরে পণ্য আইডির ফলে এই কোয়েরি তৈরি হবে এবং তারপরে আইডির মাধ্যমে প্রদত্ত পণ্যগুলি বাদ দিয়ে পণ্যগুলির জন্য একটি নতুন সংগ্রহে এটি ব্যবহার করুন। আরও ভাল এটি তেহ পণ্য সংগ্রহের একটি subquery করা যে পণ্য আইডির দ্বারা বাদ হয়।
প্রক্সি ব্লু

5

নিম্নলিখিত কোডটি আপনার পক্ষে কাজ করবে:

$catIds = array(7,8,9);
$_productCollection = Mage::getModel('catalog/product')
                ->getCollection()
                ->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id = entity_id', null, 'left')
                ->addAttributeToFilter('category_id', array('nin' => array('finset' => $catIds)))
                ->addAttributeToSelect('*');

1

অ্যান্টি-জয়েন (ম্যাজেন্টো 1.9) ব্যবহার করে আমি এটি করার কিছুটা ভাল উপায় খুঁজে পেয়েছি।

এই পদ্ধতির সুবিধা

মূল উত্তরের মাধ্যমে এটির সুবিধা হ'ল আপনি মিথ্যা ধনাত্মকতা পাবেন না এবং ফলশ্রুতিতে এটি দ্রুত এবং কম ত্রুটি-প্রবণ। উদাহরণস্বরূপ, ধরুন আপনার একক পণ্য রয়েছে:

  1. শার্ট (বিভাগগুলিতে: 1 | 2)

আপনি "সমস্ত পণ্য অন্তর্ভুক্ত নয় তা খুঁজে পেতেcategory 3category 3 চান , তারপরে সেগুলিতে যুক্ত করুন " । সুতরাং আপনি একটি NOT INক্যোয়ারী চালান , এবং এটি দুটি সারি ফিরে আসবে (name | category_id):

1. "Shirt" | 1
2. "Shirt" | 2

কোনও বড় কথা নয়, ম্যাজেন্টো এখনও কেবল প্রথম ফলাফলটি ফিরিয়ে দেবে এবং তারপরে আপনি এটি যুক্ত করুন। বাদে ! দ্বিতীয়বার এই ক্যোয়ারীটি চালিত হওয়ার পরে, আপনার একই ফলাফল রয়েছে:

1. "Shirt" | 1
2. "Shirt" | 2

এবং ম্যাজেন্টো আপনাকে বলবে যে আপনি এখনও এই শার্টটি যোগ করেন নি category 3। এটি কারণ যখন কোনও পণ্য একাধিক বিভাগের অন্তর্ভুক্ত থাকে, তখন তাদের "ক্যাটালগ_প্রডাক্ট_েন্টিটি" সারণীতে একাধিক সারি থাকবে । এবং তাই একটি LEFT JOINএকাধিক ফলাফল প্রদান করবে।

এটি অনাকাঙ্ক্ষিত কারণ

  1. আপনার ফলাফল সেটটি প্রয়োজনের চেয়ে বড় হবে, যা প্রয়োজনের চেয়ে বেশি মেমরি ব্যবহার করবে। বিশেষত তাই আপনার যদি হাজার হাজার আইটেমের খুব বড় জায় থাকে।
  2. ফলাফলগুলি মিথ্যা পজিটিভ (উদাহরণস্বরূপ in_array($categoryThree, $product->getCategories())) কিনা তা নির্ধারণ করার জন্য আপনাকে পিএইচপি-তে একটি অতিরিক্ত চেক করতে হবে, যার অর্থ আপনি অপ্রয়োজনীয় ফলাফলের মধ্য দিয়ে লুপ করবেন। এটি আপনার স্ক্রিপ্ট / কোডকে ধীর করে দেবে, বিশেষত বৃহত ইনভেন্টরিজ সহ।

সমাধান

// All products not in this category ID
$notInThisCatId = '123';

$filteredProducts = Mage::getModel('catalog/product')->getCollection();
$filteredProducts
    ->joinField('category_id', 'catalog_category_product', 'category_id', 'product_id=entity_id', ['category_id'=>$notInThisCatId], 'left');
$filteredProducts
    ->addAttributeToFilter('category_id', [
        ['null' => true]
    ]);

উত্পাদিত এসকিউএল কোয়েরিটি দেখতে পাবেন:

SELECT 
    DISTINCT `e`.*, `at_category_id`.`category_id` 
FROM `catalog_product_entity` AS `e`
LEFT JOIN `catalog_category_product` AS `at_category_id` 
    ON (at_category_id.`product_id`=e.entity_id) AND (at_category_id.category_id = '123')
WHERE (at_category_id.category_id IS NULL)
GROUP BY `e`.`entity_id`;

ব্যাখ্যা:

পণ্য এবং পণ্য দেওয়া হয়েছে <=> বিভাগ সম্পর্ক সারণী:

catalog_product_entity +-----------+ | ENTITY_ID | +-----------+ | 423 | | 424 | | 425 | +-----------+

catalog_category_product +-------------+------------+ | CATEGORY_ID | PRODUCT_ID | +-------------+------------+ | 3 | 423 | | 123 | 424 | | 3 | 425 | +-------------+------------+

আপনার ক্যোয়ারীটি বলছে, "আমাকে " ক্যাটালগ_প্রডक्ट_এন্টিটি " এ সমস্ত সারি দিন এবং " ক্যাটালগ_ক্যাটরি_প্রোডাক্ট " থেকে " বিভাগ_আইডি " কলামে পেস্ট করুন Then তারপরে আমাকে কেবল বিভাগ_id = 124" সারি দিন"

এটি একটি বাম যোগদানের কারণে এটিতে সর্বদা "ক্যাটালগ_প্রডक्ट_েন্টিটি" থেকে সারি থাকবে । যে কোনও সারি মিলে যায় না, এটি হ'ল NULL:

ফলাফল +-------------+-------------+ | ENTITY_ID | CATEGORY_ID | +-------------+-------------+ | 423 | NULL | | 424 | 123 | | 425 | NULL | +-------------+-------------+

সেখান থেকে কোয়েরিটি পরে বলে, "ঠিক আছে, এখন আমাকে যেখানে সমস্ত শ্রেণি_আইডিটি নুল" তা দিয়ে দিন


1

দেখতে যতটা সহজ তত সহজ নয়।

এটির ডিফল্ট সীমা (1024 তবে অবশ্যই বাড়ানো যেতে পারে) হিসাবে এখানে GROUP_CONCAT ভিত্তিক বিকল্পটি কমা দ্বারা নির্ধারিত পণ্য বিভাগের আইডিগুলির সাথে ঠিক আছে।

$categoryIdsToExclude = array(1, 2, 4); // Category IDs products should not be in

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

$selectCategories = $collection->getConnection()->select();
$selectCategories->from($collection->getTable('catalog/category_product'), array('product_id', 'category_id'));
$mysqlHelper = Mage::getResourceHelper('core');
$mysqlHelper->addGroupConcatColumn(
    $selectCategories,
    'category_ids_set',
    'category_id',
    ','
);
$selectCategories->group('product_id');

$collection->getSelect()->joinLeft(
    array('category_ids_set_table' => new Zend_Db_Expr('(' . $selectCategories->__toString() . ')')),
    'category_ids_set_table.product_id = e.entity_id',
    array('category_ids_set' => 'category_ids_set_table.category_ids_set')
);

foreach ($categoryIdsToExclude as $val) {
    $collection->getSelect()->where('NOT FIND_IN_SET(?, category_ids_set)', $val);
}

এছাড়াও (যদি আপনি GROUP_CONCAT পছন্দ না করেন) তবে আপনি যেখানে পণ্য আইডির কোনও প্রোডাক্ট আইডি ব্যবহার করতে পারবেন না এটি আসলে এমন বিভাগগুলিতে রয়েছে যা আপনাকে বাদ দিতে হবে (এটি এখানে দেওয়া হচ্ছে না)।

অন্য উত্তর থেকে অ্যান্টি-জয়েন পদ্ধতির কাজও করবে। তবে এই ক্ষেত্রে আপনি অতিরিক্ত শর্তাদি সহজেই যুক্ত করতে পারবেন না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.