1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-17 20:32:41 +01:00

Implement ngram search for File objects

Summary: Follows the outline in D15656 for implementing ngram search for names of File objects. Also created FileFullTextEngine, because without implementing `PhabricatorFulltextInterface`, `./bin/search` complains that `File` is not an indexable type.

Test Plan:
  - ran `./bin/storage upgrade` to apply the schema change
  - confirmed the presence of a new `file_filename_ngrams` table
  - added a couple file objects
  - ran `bin/search index --type file --force`
  - confirmed the presence of rows in `file_filename_ngrams`
  - did a few keyword searches and saw expected results

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T8788

Differential Revision: https://secure.phabricator.com/D17702
This commit is contained in:
Austin McKinley 2017-04-17 17:27:03 -07:00
parent c98be54bf4
commit 976fbee877
9 changed files with 63 additions and 5 deletions

View file

@ -0,0 +1,7 @@
CREATE TABLE {$NAMESPACE}_file.file_filename_ngrams (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
objectID INT UNSIGNED NOT NULL,
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
KEY `key_object` (objectID),
KEY `key_ngram` (ngram, objectID)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -2781,6 +2781,7 @@ phutil_register_library_map(array(
'PhabricatorFileLightboxController' => 'applications/files/controller/PhabricatorFileLightboxController.php',
'PhabricatorFileLinkView' => 'view/layout/PhabricatorFileLinkView.php',
'PhabricatorFileListController' => 'applications/files/controller/PhabricatorFileListController.php',
'PhabricatorFileNameNgrams' => 'applications/files/storage/PhabricatorFileNameNgrams.php',
'PhabricatorFileNameTransaction' => 'applications/files/xaction/PhabricatorFileNameTransaction.php',
'PhabricatorFileQuery' => 'applications/files/query/PhabricatorFileQuery.php',
'PhabricatorFileROT13StorageFormat' => 'applications/files/format/PhabricatorFileROT13StorageFormat.php',
@ -7908,6 +7909,8 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
'PhabricatorConduitResultInterface',
'PhabricatorIndexableInterface',
'PhabricatorNgramsInterface',
),
'PhabricatorFileAES256StorageFormat' => 'PhabricatorFileStorageFormat',
'PhabricatorFileBundleLoader' => 'Phobject',
@ -7954,6 +7957,7 @@ phutil_register_library_map(array(
'PhabricatorFileLightboxController' => 'PhabricatorFileController',
'PhabricatorFileLinkView' => 'AphrontTagView',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileNameNgrams' => 'PhabricatorSearchNgrams',
'PhabricatorFileNameTransaction' => 'PhabricatorFileTransactionType',
'PhabricatorFileQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorFileROT13StorageFormat' => 'PhabricatorFileStorageFormat',

View file

@ -25,7 +25,8 @@ final class PhabricatorFileDeleteController extends PhabricatorFileController {
}
if ($request->isFormPost()) {
$file->delete();
$engine = new PhabricatorDestructionEngine();
$engine->destroyObject($file);
return id(new AphrontRedirectResponse())->setURI('/file/');
}

View file

@ -71,7 +71,7 @@ final class PhabricatorFileEditor
}
protected function supportsSearch() {
return false;
return true;
}
}

View file

@ -18,8 +18,10 @@ final class PhabricatorFileTemporaryGarbageCollector
'ttl < %d LIMIT 100',
PhabricatorTime::getNow());
$engine = new PhabricatorDestructionEngine();
foreach ($files as $file) {
$file->delete();
$engine->destroyObject($file);
}
return (count($files) == 100);

View file

@ -119,6 +119,12 @@ final class PhabricatorFileQuery
return $this;
}
public function withNameNgrams($ngrams) {
return $this->withNgramsConstraint(
id(new PhabricatorFileNameNgrams()),
$ngrams);
}
public function showOnlyExplicitUploads($explicit_uploads) {
$this->explicitUploads = $explicit_uploads;
return $this;

View file

@ -38,6 +38,10 @@ final class PhabricatorFileSearchEngine
id(new PhabricatorSearchDateField())
->setKey('createdEnd')
->setLabel(pht('Created Before')),
id(new PhabricatorSearchTextField())
->setLabel(pht('Name Contains'))
->setKey('name')
->setDescription(pht('Search for files by name substring.')),
);
}
@ -68,6 +72,10 @@ final class PhabricatorFileSearchEngine
$query->withDateCreatedBefore($map['createdEnd']);
}
if ($map['name'] !== null) {
$query->withNameNgrams($map['name']);
}
return $query;
}

View file

@ -28,7 +28,9 @@ final class PhabricatorFile extends PhabricatorFileDAO
PhabricatorFlaggableInterface,
PhabricatorPolicyInterface,
PhabricatorDestructibleInterface,
PhabricatorConduitResultInterface {
PhabricatorConduitResultInterface,
PhabricatorIndexableInterface,
PhabricatorNgramsInterface {
const METADATA_IMAGE_WIDTH = 'width';
const METADATA_IMAGE_HEIGHT = 'height';
@ -87,7 +89,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
'metadata' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text255?',
'name' => 'sort255?',
'mimeType' => 'text255?',
'byteSize' => 'uint64',
'storageEngine' => 'text32',
@ -1585,4 +1587,14 @@ final class PhabricatorFile extends PhabricatorFileDAO
return array();
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
public function newNgrams() {
return array(
id(new PhabricatorFileNameNgrams())
->setValue($this->getName()),
);
}
}

View file

@ -0,0 +1,18 @@
<?php
final class PhabricatorFileNameNgrams
extends PhabricatorSearchNgrams {
public function getNgramKey() {
return 'filename';
}
public function getColumnName() {
return 'name';
}
public function getApplicationName() {
return 'file';
}
}