Skip to content

Commit 0777d99

Browse files
committed
6775 Add new command line options for splitting up indexing into slices
1 parent b7e4a46 commit 0777d99

File tree

2 files changed

+99
-5
lines changed

2 files changed

+99
-5
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,22 @@ 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
{
73-
/** @var $productCollection Mage_Catalog_Model_Resource_Product_Collection */
7475
$productCollection = Mage::getResourceModel('catalog/product_collection');
76+
77+
/** @var $productCollection Mage_Catalog_Model_Resource_Product_Collection */
78+
if ((!is_null($sliceId)) && (!is_null($totalNumberSlices))) {
79+
if ($sliceId == $totalNumberSlices) {
80+
$sliceId = 0;
81+
}
82+
$productCollection->getSelect()->where('e.entity_id % ' . intval($totalNumberSlices) . ' = ' . intval($sliceId));
83+
}
84+
7585
return $productCollection->getAllIds();
7686
}
7787

src/shell/integernet-solr.php

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ public function run()
3232
$entityTypes = explode(',', $entityTypes);
3333
}
3434

35+
$sliceId = null;
36+
$totalNumberSlices = null;
37+
if ($sliceArg = $this->getArg('slice')) {
38+
list($sliceId, $totalNumberSlices) = explode('/', $sliceArg);
39+
}
40+
3541
$emptyIndex = true;
3642
if ($this->getArg('emptyindex')) {
3743
$emptyIndex = 'force';
@@ -43,11 +49,25 @@ public function run()
4349
$autoloader->createAndRegister();
4450

4551
try {
52+
$this->_checkSliceArgument($sliceArg);
53+
4654
if (in_array('product', $entityTypes)) {
55+
4756
$indexer = Mage::helper('integernet_solr')->factory()->getProductIndexer();
48-
$indexer->reindex(null, $emptyIndex, $storeIds);
57+
58+
if ($this->getArg('use-swap-core')) {
59+
$indexer->activateSwapCore();
60+
}
61+
$indexer->reindex(null, $emptyIndex, $storeIds, $sliceId, $totalNumberSlices);
62+
if ($this->getArg('use-swap-core')) {
63+
$indexer->deactivateSwapCore();
64+
}
65+
4966
$storeIdsString = implode(', ', $storeIds);
5067
echo "Solr product index rebuilt for Stores {$storeIdsString}.\n";
68+
if (!is_null($sliceId) && !is_null($totalNumberSlices)) {
69+
echo '(Slice ' . $sliceId . ' of ' . $totalNumberSlices . ')' . "\n";
70+
}
5171
}
5272

5373
if (in_array('page', $entityTypes) && $this->_useCmsIndexer()) {
@@ -67,6 +87,35 @@ public function run()
6787
echo $e->getMessage() . "\n";
6888
}
6989

90+
} else if ($this->getArg('clear')) {
91+
$storeIdentifiers = $this->getArg('stores');
92+
if (!$storeIdentifiers) {
93+
$storeIdentifiers = 'all';
94+
}
95+
$storeIds = $this->_getStoreIds($storeIdentifiers);
96+
$indexer = Mage::helper('integernet_solr')->factory()->getProductIndexer();
97+
foreach($storeIds as $storeId) {
98+
$indexer->clearIndex($storeId);
99+
}
100+
$storeIdsString = implode(', ', $storeIds);
101+
echo "Solr product index cleared for Stores {$storeIdsString}.\n";
102+
103+
} else if ($this->getArg('swap_cores')) {
104+
$storeIdentifiers = $this->getArg('stores');
105+
if (!$storeIdentifiers) {
106+
$storeIdentifiers = 'all';
107+
}
108+
$storeIds = $this->_getStoreIds($storeIdentifiers);
109+
$indexer = Mage::helper('integernet_solr')->factory()->getProductIndexer();
110+
try {
111+
$indexer->checkSwapCoresConfiguration($storeIds);
112+
$indexer->swapCores($storeIds);
113+
$storeIdsString = implode(', ', $storeIds);
114+
echo "Solr cores swapped for Stores {$storeIdsString}.\n";
115+
} catch (Exception $e) {
116+
echo $e->getMessage() . "\n";
117+
}
118+
70119
} else {
71120
echo $this->usageHelp();
72121
}
@@ -82,12 +131,21 @@ public function usageHelp()
82131
Usage: php -f integernet-solr.php -- [options]
83132
php -f integernet-solr.php -- reindex --stores de
84133
php -f integernet-solr.php -- reindex --stores all --emptyindex
134+
php -f integernet-solr.php -- reindex --stores 1 --slice 1/5 --use-swap-core
135+
php -f integernet-solr.php -- clear --stores 1
85136
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.
137+
reindex Reindex solr for given stores (see "stores" param)
138+
--stores <stores> Reindex given stores (can be store id, store code, comma seperated. Or "all".) If not set, reindex all stores.
88139
--emptyindex Force emptying the solr index for the given store(s). If not set, configured value is used.
89140
--noemptyindex Force not emptying the solr index for the given store(s). If not set, configured value is used.
90141
--types <types> Restrict indexing to certain entity types, i.e. "product", "category" or "page" (comma separated). Or "all". If not set, reindex products.
142+
--slice <number>/<total_number>, i.e. "1/5" or "2/5". Use this if you want to index only a part of the products, i.e. for letting indexing run in parallel (for products only).
143+
--use-swap-core Use swap core for indexing instead of live core (only if configured correctly). This is useful when using slices (see above), it's not needed otherwise.
144+
145+
clear Clear solr product index for given stores (see "stores" param)
146+
147+
swap-cores Swap cores. This is useful when using slices (see above) after indexing with the "--use-swap-core" param, it's not needed otherwise. See "stores" param.
148+
91149
help This help
92150
93151
USAGE;
@@ -149,6 +207,32 @@ protected function _useCmsIndexer()
149207
{
150208
return Mage::helper('core')->isModuleEnabled('IntegerNet_SolrPro') && Mage::getStoreConfigFlag('integernet_solr/cms/is_active');
151209
}
210+
211+
/**
212+
* @param string $sliceArg
213+
* @throws InvalidArgumentException
214+
*/
215+
protected function _checkSliceArgument($sliceArg)
216+
{
217+
if (!strlen($sliceArg)) {
218+
return;
219+
}
220+
if (strpos($sliceArg, '/') < 1) {
221+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20"');
222+
}
223+
list($sliceId, $totalNumberSlices) = explode('/', $sliceArg);
224+
$sliceId = intval($sliceId);
225+
$totalNumberSlices = intval($totalNumberSlices);
226+
if (!is_integer($sliceId) || !is_integer($totalNumberSlices)) {
227+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20", only containing integer numbers before/after the slash.');
228+
}
229+
if ($totalNumberSlices < 2) {
230+
throw new InvalidArgumentException('The "slice" argument must be of format "1/5" or "20/20". The second number must be higher than 1.');
231+
}
232+
if ($sliceId < 1 || $sliceId > $totalNumberSlices) {
233+
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).');
234+
}
235+
}
152236
}
153237

154238
$shell = new IntegerNet_Solr_Shell();

0 commit comments

Comments
 (0)