Skip to content

Commit 59b37e9

Browse files
committed
enable reindexing of library to ES
- added boolean column deindexed_from_es to the library table. It should be set to true when the library is deleted from ES. - GET /fulltext/reindex returns reindexingStatus that's one of indexed, indexing or deindexed. 'deindexed' if deindexed_from_es is true. 'indexed' if # of indexed items = # of indexable attachments, and 'indexing' otherwise. - POST /fulltext/reindex adds an event to SQS that triggers full-text-indexer lambda that handles reindeixing and sets deindexed_from_es = false. Only possible if deindexed_from_es is initially true.
1 parent 17e67f4 commit 59b37e9

File tree

8 files changed

+97
-1
lines changed

8 files changed

+97
-1
lines changed

controllers/FullTextController.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,48 @@ public function itemContent() {
157157

158158
$this->end();
159159
}
160+
161+
public function reindex() {
162+
$this->allowMethods(['POST', 'GET']);
163+
164+
// General library access
165+
if (!$this->permissions->canAccess($this->objectLibraryID)) {
166+
$this->e403();
167+
}
168+
169+
$isDeindexed = Zotero_Libraries::checkEsIndexStatus($this->objectLibraryID);
170+
171+
// GET - return indexing status of ES: indexing, indexed, deindexed
172+
if ($this->method == "GET") {
173+
// Current count of records in ES
174+
$esCount = Zotero_FullText::countInLibrary($this->objectLibraryID);
175+
// Expected count of records in ES
176+
$expectedCount = Zotero_Libraries::countIndexableAttachments($this->objectLibraryID);
177+
178+
if ($esCount === $expectedCount) {
179+
$result = ["reindexingStatus" => "indexed"];
180+
}
181+
else if ($isDeindexed) {
182+
$result = ["reindexingStatus" => "deindexed"];
183+
}
184+
else {
185+
$result = ["reindexingStatus" => "indexing", "indexedCount" => $esCount, "expectedCount" => $expectedCount];
186+
}
187+
echo Zotero_Utilities::formatJSON($result);
188+
$this->end();
189+
}
190+
191+
// POST - request reindexing if the library was removed from ES
192+
if (!$isDeindexed) {
193+
$this->e400("Request was already submitted or the library was not removed from ElasticSearch");
194+
}
195+
196+
// Send event to reindexing queue
197+
Z_SQS::send(Z_CONFIG::$REINDEX_QUEUE_URL, json_encode(['libraryID' => $this->objectLibraryID]));
198+
199+
// Update DB
200+
Zotero_Libraries::setEsIndexStatus($this->objectLibraryID, 0);
201+
$this->end();
202+
}
203+
160204
}

include/SQS.inc.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public static function deleteBatch($queueURL, $batchEntries) {
102102

103103
private static function load() {
104104
if (!self::$sqs) {
105-
self::$sqs = Z_Core::$AWS->get('sqs');
105+
self::$sqs = Z_Core::$AWS->createSQS();
106106
}
107107
}
108108
}

include/config/config.inc.php-sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,7 @@ class Z_CONFIG {
8989
public static $CACHE_VERSION_ITEM_DATA = 1;
9090
public static $CACHE_VERSION_RESPONSE_JSON_COLLECTION = 1;
9191
public static $CACHE_VERSION_RESPONSE_JSON_ITEM = 1;
92+
93+
public static $REINDEX_QUEUE_URL = "";
9294
}
9395
?>

include/config/routes.inc.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
$router->map('/users/i:objectUserID/fulltext', array('controller' => 'FullText', 'action' => 'fulltext'));
4343
//$router->map('/users/i:objectUserID/publications/fulltext', ['controller' => 'FullText', 'action' => 'fulltext', 'extra' => ['publications' => true]]);
4444
$router->map('/groups/i:objectGroupID/fulltext', array('controller' => 'FullText', 'action' => 'fulltext'));
45+
$router->map('/groups/i:objectGroupID/fulltext/reindex', array('controller' => 'FullText', 'action' => 'reindex'));
46+
$router->map('/users/i:objectUserID/fulltext/reindex', array('controller' => 'FullText', 'action' => 'reindex'));
4547

4648
// All trashed items
4749
$router->map('/users/i:objectUserID/items/trash', array('controller' => 'Items', 'extra' => array('subset' => 'trash')));
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/php -d mysqlnd.net_read_timeout=3600
2+
<?php
3+
set_include_path("../../../include");
4+
require("header.inc.php");
5+
6+
Zotero_DB::query("ALTER TABLE libraries ADD COLUMN deindexed_from_es tinyint(1) unsigned NOT NULL DEFAULT '0';");

misc/master.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ CREATE TABLE `libraries` (
184184
`lastUpdated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
185185
`version` int(10) unsigned NOT NULL DEFAULT '0',
186186
`shardID` smallint(5) unsigned NOT NULL,
187+
`deindexed_from_es` tinyint(1) unsigned NOT NULL DEFAULT '0',
187188
PRIMARY KEY (`libraryID`),
188189
KEY `shardID` (`shardID`)
189190
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

model/FullText.inc.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,25 @@ public static function searchInLibrary($libraryID, $searchText) {
259259
}
260260
return $keys;
261261
}
262+
263+
public static function countInLibrary($libraryID) {
264+
$params = [
265+
'index' => self::$elasticsearchType . "_index",
266+
'body' => [
267+
'query' => [
268+
'bool' => [
269+
'filter' => [
270+
'term' => [
271+
'libraryID' => $libraryID
272+
]
273+
]
274+
]
275+
]
276+
]
277+
];
278+
$resp = Z_Core::$ES->count($params);
279+
return $resp['count'];
280+
}
262281

263282
public static function deleteItemContent(Zotero_Item $item) {
264283
$libraryID = $item->libraryID;

model/Libraries.inc.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ public static function exists($libraryID) {
5353
$sql = "SELECT COUNT(*) FROM libraries WHERE libraryID=?";
5454
return !!Zotero_DB::valueQuery($sql, $libraryID);
5555
}
56+
57+
public static function countIndexableAttachments($libraryID) {
58+
$attachmentIds = Zotero_DB::columnQuery(
59+
"SELECT itemTypeID FROM itemTypes "
60+
. "WHERE itemTypeName IN ('attachment') "
61+
);
62+
$sql = "SELECT COUNT(*) as count FROM items INNER JOIN itemAttachments USING (itemID)"
63+
. "WHERE NOT(linkMode='LINKED_URL') AND libraryID=? AND itemTypeID IN (" . implode(",", $attachmentIds) . ")";
64+
$count = Zotero_DB::query($sql, $libraryID, Zotero_Shards::getByLibraryID($libraryID));
65+
return $count[0]['count'];
66+
}
67+
68+
public static function checkEsIndexStatus($libraryID) {
69+
$sql = "SELECT deindexed_from_es FROM libraries WHERE libraryID=?";
70+
$isDeleted = Zotero_DB::query($sql, $libraryID);
71+
return $isDeleted[0]['deindexed_from_es'] == 1;
72+
}
73+
74+
public static function setEsIndexStatus($libraryID, $deindexed) {
75+
$sql = "UPDATE libraries SET deindexed_from_es=? WHERE libraryID=?";
76+
Zotero_DB::query($sql, [$deindexed, $libraryID]);
77+
}
5678

5779

5880
public static function getName($libraryID) {

0 commit comments

Comments
 (0)