Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / search / fulltextstorage / PhabricatorFerretFulltextStorageEngine.php
blobfa03bcafddac0f6cf2ac23f6c9f128eca3a1abf9
1 <?php
3 final class PhabricatorFerretFulltextStorageEngine
4 extends PhabricatorFulltextStorageEngine {
6 private $fulltextTokens = array();
7 private $engineLimits;
9 public function getEngineIdentifier() {
10 return 'mysql';
13 public function getHostType() {
14 return new PhabricatorMySQLSearchHost($this);
17 public function reindexAbstractDocument(
18 PhabricatorSearchAbstractDocument $doc) {
20 // NOTE: The Ferret engine indexes are rebuilt by an extension rather than
21 // by the main fulltext engine, and are always built regardless of
22 // configuration.
24 return;
27 public function executeSearch(PhabricatorSavedQuery $query) {
28 $all_objects = id(new PhutilClassMapQuery())
29 ->setAncestorClass('PhabricatorFerretInterface')
30 ->execute();
32 $type_map = array();
33 foreach ($all_objects as $object) {
34 $phid_type = phid_get_type($object->generatePHID());
36 $type_map[$phid_type] = array(
37 'object' => $object,
38 'engine' => $object->newFerretEngine(),
42 $types = $query->getParameter('types');
43 if ($types) {
44 $type_map = array_select_keys($type_map, $types);
47 $offset = (int)$query->getParameter('offset', 0);
48 $limit = (int)$query->getParameter('limit', 25);
50 // NOTE: For now, it's okay to query with the omnipotent viewer here
51 // because we're just returning PHIDs which we'll filter later.
52 $viewer = PhabricatorUser::getOmnipotentUser();
54 $type_results = array();
55 $metadata = array();
56 foreach ($type_map as $type => $spec) {
57 $engine = $spec['engine'];
58 $object = $spec['object'];
60 $local_query = new PhabricatorSavedQuery();
61 $local_query->setParameter('query', $query->getParameter('query'));
63 $project_phids = $query->getParameter('projectPHIDs');
64 if ($project_phids) {
65 $local_query->setParameter('projectPHIDs', $project_phids);
68 $subscriber_phids = $query->getParameter('subscriberPHIDs');
69 if ($subscriber_phids) {
70 $local_query->setParameter('subscriberPHIDs', $subscriber_phids);
73 $search_engine = $engine->newSearchEngine()
74 ->setViewer($viewer);
76 $engine_query = $search_engine->buildQueryFromSavedQuery($local_query)
77 ->setViewer($viewer);
79 $engine_query
80 ->withFerretQuery($engine, $query)
81 ->setOrder('relevance')
82 ->setLimit($offset + $limit);
84 $results = $engine_query->execute();
85 $results = mpull($results, null, 'getPHID');
86 $type_results[$type] = $results;
88 $metadata += $engine_query->getFerretMetadata();
90 if (!$this->fulltextTokens) {
91 $this->fulltextTokens = $engine_query->getFerretTokens();
95 $list = array();
96 foreach ($type_results as $type => $results) {
97 $list += $results;
100 // Currently, the list is grouped by object type. For example, all the
101 // tasks might be first, then all the revisions, and so on. In each group,
102 // the results are ordered properly.
104 // Reorder the results so that the highest-ranking results come first,
105 // no matter which object types they belong to.
107 $metadata = msortv($metadata, 'getRelevanceSortVector');
108 $list = array_select_keys($list, array_keys($metadata)) + $list;
110 $result_slice = array_slice($list, $offset, $limit, true);
111 return array_keys($result_slice);
114 public function indexExists() {
115 return true;
118 public function getIndexStats() {
119 return false;
122 public function getFulltextTokens() {
123 return $this->fulltextTokens;