Skip to content

Commit

Permalink
EZP-30296: Large API subtree delete leads to serious Solr index incon…
Browse files Browse the repository at this point in the history
…sistencies (#150)
  • Loading branch information
kmadejski authored and lserwatka committed Oct 3, 2019
1 parent 2918157 commit d1f4042
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"require": {
"php": "~5.6|~7.0",
"ezsystems/ezpublish-kernel": "~6.7.10@dev|^6.13.6@dev|~7.3.5@dev|^7.4.3@dev",
"ezsystems/ezpublish-kernel": "~6.7.10@dev|^6.13.6@dev|~7.3.5@dev|~7.4.3@dev",
"netgen/query-translator": "^1.0"
},
"require-dev": {
Expand Down
26 changes: 20 additions & 6 deletions lib/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
*/
class Handler implements SearchHandlerInterface, Capable
{
/* Solr's maxBooleanClauses config value is 1024 */
const SOLR_BULK_REMOVE_LIMIT = 1000;
/* 16b max unsigned integer value due to Solr (JVM) limitations */
const SOLR_MAX_QUERY_LIMIT = 65535;
const DEFAULT_QUERY_LIMIT = 1000;

/**
* Content locator gateway.
*
Expand Down Expand Up @@ -328,7 +334,7 @@ public function commit($flush = false)
*/
protected function deleteAllItemsWithoutAdditionalLocation($locationId)
{
$query = $this->prepareQuery();
$query = $this->prepareQuery(self::SOLR_MAX_QUERY_LIMIT);
$query->filter = new Criterion\LogicalAnd(
[
$this->allItemsWithinLocation($locationId),
Expand All @@ -340,9 +346,15 @@ protected function deleteAllItemsWithoutAdditionalLocation($locationId)
$this->gateway->searchAllEndpoints($query)
);

$contentDocumentIds = [];

foreach ($searchResult->searchHits as $hit) {
$idPrefix = $this->mapper->generateContentDocumentId($hit->valueObject->id);
$this->gateway->deleteByQuery("_root_:{$idPrefix}*");
$contentDocumentIds[] = $this->mapper->generateContentDocumentId($hit->valueObject->id) . '*';
}

foreach (\array_chunk(\array_unique($contentDocumentIds), self::SOLR_BULK_REMOVE_LIMIT) as $ids) {
$query = '_root_:(' . implode(' OR ', $ids) . ')';
$this->gateway->deleteByQuery($query);
}
}

Expand All @@ -351,7 +363,7 @@ protected function deleteAllItemsWithoutAdditionalLocation($locationId)
*/
protected function updateAllElementsWithAdditionalLocation($locationId)
{
$query = $this->prepareQuery();
$query = $this->prepareQuery(self::SOLR_MAX_QUERY_LIMIT);
$query->filter = new Criterion\LogicalAnd(
[
$this->allItemsWithinLocation($locationId),
Expand Down Expand Up @@ -380,14 +392,16 @@ protected function updateAllElementsWithAdditionalLocation($locationId)
/**
* Prepare standard query for delete purpose.
*
* @param int $limit
*
* @return Query
*/
protected function prepareQuery()
protected function prepareQuery($limit = self::DEFAULT_QUERY_LIMIT)
{
return new Query(
[
'query' => new Criterion\MatchAll(),
'limit' => 1000,
'limit' => $limit,
'offset' => 0,
]
);
Expand Down

0 comments on commit d1f4042

Please sign in to comment.