Skip to content

Commit 6837b8d

Browse files
authored
Merge pull request #20 from integer-net/slices
Slices
2 parents 699ba07 + 6fe1aff commit 6837b8d

File tree

2 files changed

+121
-3
lines changed

2 files changed

+121
-3
lines changed

src/app/code/community/IntegerNet/Solr/Model/Bridge/ProductRepository.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,25 @@ function($parentId, $childrenIds) {
6666
}
6767

6868
/**
69+
* @param null|int $sliceId
70+
* @param null|int $totalNumberSlices
6971
* @return int[]
7072
*/
71-
public function getAllProductIds()
73+
public function getAllProductIds($sliceId = null, $totalNumberSlices = null)
7274
{
7375
// Fixes a bug with flat product collections called for different stores, see https://magento.stackexchange.com/q/30956/2207
7476
Mage::unregister('_resource_singleton/catalog/product_flat');
7577

7678
/** @var $productCollection Mage_Catalog_Model_Resource_Product_Collection */
7779
$productCollection = Mage::getResourceModel('catalog/product_collection');
80+
81+
if ((!is_null($sliceId)) && (!is_null($totalNumberSlices))) {
82+
if ($sliceId == $totalNumberSlices) {
83+
$sliceId = 0;
84+
}
85+
$productCollection->getSelect()->where('e.entity_id % ' . intval($totalNumberSlices) . ' = ' . intval($sliceId));
86+
}
87+
7888
return $productCollection->getAllIds();
7989
}
8090

src/shell/integernet-solr.php

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,73 @@ public function run()
6767
echo $e->getMessage() . "\n";
6868
}
6969

70+
} else if ($this->getArg('reindex_slice')) {
71+
$storeIdentifiers = $this->getArg('stores');
72+
if (!$storeIdentifiers) {
73+
$storeIdentifiers = 'all';
74+
}
75+
$storeIds = $this->_getStoreIds($storeIdentifiers);
76+
77+
$autoloader = new IntegerNet_Solr_Helper_Autoloader();
78+
$autoloader->createAndRegister();
79+
80+
try {
81+
$sliceArg = $this->getArg('slice');
82+
$this->_checkSliceArgument($sliceArg);
83+
list($sliceId, $totalNumberSlices) = explode('/', $sliceArg);
84+
85+
$indexer = Mage::helper('integernet_solr')->factory()->getProductIndexer();
86+
87+
if ($this->getArg('use_swap_core')) {
88+
$indexer->activateSwapCore();
89+
}
90+
$indexer->reindex(null, false, $storeIds, $sliceId, $totalNumberSlices);
91+
if ($this->getArg('use_swap_core')) {
92+
$indexer->deactivateSwapCore();
93+
}
94+
95+
$storeIdsString = implode(', ', $storeIds);
96+
echo "Solr product index rebuilt for Stores {$storeIdsString}.\n";
97+
echo '(Slice ' . $sliceId . ' of ' . $totalNumberSlices . ')' . "\n";
98+
} catch (Exception $e) {
99+
echo $e->getMessage() . "\n";
100+
}
101+
102+
} else if ($this->getArg('clear')) {
103+
$storeIdentifiers = $this->getArg('stores');
104+
if (!$storeIdentifiers) {
105+
$storeIdentifiers = 'all';
106+
}
107+
$storeIds = $this->_getStoreIds($storeIdentifiers);
108+
$indexer = Mage::helper('integernet_solr')->factory()->getProductIndexer();
109+
if ($this->getArg('use_swap_core')) {
110+
$indexer->activateSwapCore();
111+
}
112+
foreach($storeIds as $storeId) {
113+
$indexer->clearIndex($storeId);
114+
}
115+
if ($this->getArg('use_swap_core')) {
116+
$indexer->deactivateSwapCore();
117+
}
118+
$storeIdsString = implode(', ', $storeIds);
119+
echo "Solr product index cleared for Stores {$storeIdsString}.\n";
120+
121+
} else if ($this->getArg('swap_cores')) {
122+
$storeIdentifiers = $this->getArg('stores');
123+
if (!$storeIdentifiers) {
124+
$storeIdentifiers = 'all';
125+
}
126+
$storeIds = $this->_getStoreIds($storeIdentifiers);
127+
$indexer = Mage::helper('integernet_solr')->factory()->getProductIndexer();
128+
try {
129+
$indexer->checkSwapCoresConfiguration($storeIds);
130+
$indexer->swapCores($storeIds);
131+
$storeIdsString = implode(', ', $storeIds);
132+
echo "Solr cores swapped for Stores {$storeIdsString}.\n";
133+
} catch (Exception $e) {
134+
echo $e->getMessage() . "\n";
135+
}
136+
70137
} else {
71138
echo $this->usageHelp();
72139
}
@@ -82,12 +149,27 @@ public function usageHelp()
82149
Usage: php -f integernet-solr.php -- [options]
83150
php -f integernet-solr.php -- reindex --stores de
84151
php -f integernet-solr.php -- reindex --stores all --emptyindex
152+
php -f integernet-solr.php -- reindex --stores 1 --slice 1/5 --use_swap_core
153+
php -f integernet-solr.php -- clear --stores 1
85154
86-
reindex reindex solr for given stores (see "stores" param)
87-
--stores <stores> reindex given stores (can be store id, store code, comma seperated. Or "all".) If not set, reindex all stores.
155+
reindex Reindex solr for given stores (see "stores" param)
156+
--stores <stores> Reindex given stores (can be store id, store code, comma seperated. Or "all".) If not set, reindex all stores.
88157
--emptyindex Force emptying the solr index for the given store(s). If not set, configured value is used.
89158
--noemptyindex Force not emptying the solr index for the given store(s). If not set, configured value is used.
90159
--types <types> Restrict indexing to certain entity types, i.e. "product", "category" or "page" (comma separated). Or "all". If not set, reindex products.
160+
161+
reindex_slice Reindex solr for given stores (see "stores" param). Use this if you want to index only a part of the products, i.e. for letting indexing run in parallel (for products only).
162+
--slice <number>/<total_number>, i.e. "1/5" or "2/5".
163+
--stores <stores> Reindex given stores (can be store id, store code, comma seperated. Or "all".) If not set, reindex all stores.
164+
--use_swap_core Use swap core for indexing instead of live solr core (only if configured correctly).
165+
166+
clear Clear solr product index for given stores (see "stores" param and "use_swap_core" param)
167+
--stores <stores> Reindex given stores (can be store id, store code, comma seperated. Or "all".) If not set, reindex all stores.
168+
--use_swap_core Use swap core for clearing instead of live solr core (only if configured correctly).
169+
170+
swap_cores Swap cores. This is useful if using slices (see above) after indexing with the "--use_swap_core" param; it's not needed otherwise.
171+
--stores <stores> Reindex given stores (can be store id, store code, comma seperated. Or "all".) If not set, reindex all stores.
172+
91173
help This help
92174
93175
USAGE;
@@ -149,6 +231,32 @@ protected function _useCmsIndexer()
149231
{
150232
return Mage::helper('core')->isModuleEnabled('IntegerNet_SolrPro') && Mage::getStoreConfigFlag('integernet_solr/cms/is_active');
151233
}
234+
235+
/**
236+
* @param string $sliceArg
237+
* @throws InvalidArgumentException
238+
*/
239+
protected function _checkSliceArgument($sliceArg)
240+
{
241+
if (!strlen($sliceArg)) {
242+
throw new InvalidArgumentException('The "slice" argument must be given.');
243+
}
244+
if (strpos($sliceArg, '/') < 1) {
245+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20"');
246+
}
247+
list($sliceId, $totalNumberSlices) = explode('/', $sliceArg);
248+
$sliceId = intval($sliceId);
249+
$totalNumberSlices = intval($totalNumberSlices);
250+
if (!is_integer($sliceId) || !is_integer($totalNumberSlices)) {
251+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20", only containing integer numbers before/after the slash.');
252+
}
253+
if ($totalNumberSlices < 2) {
254+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20". The second number must be higher than 1.');
255+
}
256+
if ($sliceId < 1 || $sliceId > $totalNumberSlices) {
257+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20". The first number is invalid, should be between 1 and the second number (including those).');
258+
}
259+
}
152260
}
153261

154262
$shell = new IntegerNet_Solr_Shell();

0 commit comments

Comments
 (0)