1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

Improve search functionality.

Summary:

Test Plan:

Reviewers:

CC:
This commit is contained in:
epriestley 2011-02-18 17:16:00 -08:00
parent eec3e8e3aa
commit 505c82236d
14 changed files with 232 additions and 22 deletions

View file

@ -26,6 +26,20 @@ class ManiphestTaskSelectorSearchController extends ManiphestController {
$query->setQuery($request->getStr('query')); $query->setQuery($request->getStr('query'));
$query->setParameter('type', 'TASK'); $query->setParameter('type', 'TASK');
switch ($request->getStr('filter')) {
case 'assigned':
$query->setParameter('owner', array($user->getPHID()));
$query->setParameter('open', 1);
break;
case 'created';
$query->setParameter('author', array($user->getPHID()));
$query->setParameter('open', 1);
break;
case 'open':
$query->setParameter('open', 1);
break;
}
$exec = new PhabricatorSearchMySQLExecutor(); $exec = new PhabricatorSearchMySQLExecutor();
$results = $exec->executeSearch($query); $results = $exec->executeSearch($query);
$results = ipull($results, 'phid'); $results = ipull($results, 'phid');

View file

@ -29,7 +29,7 @@ class PhabricatorHandleObjectSelectorDataView {
return array( return array(
'phid' => $handle->getPHID(), 'phid' => $handle->getPHID(),
'name' => $handle->getFullName(), 'name' => $handle->getFullName(),
'href' => $handle->getURI(), 'uri' => $handle->getURI(),
); );
} }
} }

View file

@ -21,5 +21,6 @@ final class PhabricatorSearchField {
const FIELD_TITLE = 'titl'; const FIELD_TITLE = 'titl';
const FIELD_BODY = 'body'; const FIELD_BODY = 'body';
const FIELD_TEST_PLAN = 'tpln'; const FIELD_TEST_PLAN = 'tpln';
const FIELD_COMMENT = 'cmnt';
} }

View file

@ -22,5 +22,9 @@ final class PhabricatorSearchRelationship {
const RELATIONSHIP_REVIEWER = 'revw'; const RELATIONSHIP_REVIEWER = 'revw';
const RELATIONSHIP_SUBSCRIBER = 'subs'; const RELATIONSHIP_SUBSCRIBER = 'subs';
const RELATIONSHIP_COMMENTER = 'comm'; const RELATIONSHIP_COMMENTER = 'comm';
const RELATIONSHIP_OWNER = 'ownr';
const RELATIONSHIP_OPEN = 'open';
const RELATIONSHIP_TOUCH = 'poke';
} }

View file

@ -38,12 +38,47 @@ class PhabricatorSearchController extends PhabricatorSearchBaseController {
if ($request->isFormPost()) { if ($request->isFormPost()) {
$query->setQuery($request->getStr('query')); $query->setQuery($request->getStr('query'));
if (strlen($request->getStr('type'))) {
$query->setParameter('type', $request->getStr('type'));
}
if ($request->getArr('author')) {
$query->setParameter('author', $request->getArr('author'));
}
if ($request->getInt('open')) {
$query->setParameter('open', $request->getInt('open'));
}
$query->save(); $query->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/search/'.$query->getID().'/'); ->setURI('/search/'.$query->getID().'/');
} }
} }
$options = array(
'' => 'All Documents',
'DREV' => 'Differential Revisions',
'TASK' => 'Maniphest Tasks',
);
$status_options = array(
0 => 'Open and Closed Documents',
1 => 'Open Documents',
);
$phids = array_merge(
$query->getParameter('author', array())
);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$author_value = array_select_keys(
$handles,
$query->getParameter('author', array()));
$author_value = mpull($author_value, 'getFullName', 'getPHID');
$search_form = new AphrontFormView(); $search_form = new AphrontFormView();
$search_form $search_form
@ -54,6 +89,24 @@ class PhabricatorSearchController extends PhabricatorSearchBaseController {
->setLabel('Search') ->setLabel('Search')
->setName('query') ->setName('query')
->setValue($query->getQuery())) ->setValue($query->getQuery()))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Document Type')
->setName('type')
->setOptions($options)
->setValue($query->getParameter('type')))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('author')
->setLabel('Author')
->setDatasource('/typeahead/common/users/')
->setValue($author_value))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Document Status')
->setName('open')
->setOptions($status_options)
->setValue($query->getParameter('open')))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->setValue('Search')); ->setValue('Search'));

View file

@ -60,18 +60,33 @@ class PhabricatorSearchMySQLExecutor extends PhabricatorSearchExecutor {
} }
if ($query->getParameter('type')) { if ($query->getParameter('type')) {
if (strlen($q)) {
// TODO: verify that this column actually does something useful in query
// plans once we have nontrivial amounts of data.
$where[] = qsprintf(
$conn_r,
'field.phidType = %s',
$query->getParameter('type'));
}
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,
'document.documentType = %s', 'document.documentType = %s',
$query->getParameter('type')); $query->getParameter('type'));
} }
/*
$join[] = $this->joinRelationship( $join[] = $this->joinRelationship(
$conn_r, $conn_r,
$query, $query,
'author', 'author',
AdjutantRelationship::RELATIONSHIP_AUTHOR); PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'open',
PhabricatorSearchRelationship::RELATIONSHIP_OPEN);
/*
$join[] = $this->joinRelationship( $join[] = $this->joinRelationship(
$conn_r, $conn_r,
$query, $query,
@ -118,20 +133,36 @@ class PhabricatorSearchMySQLExecutor extends PhabricatorSearchExecutor {
} }
protected function joinRelationship($conn, $query, $field, $type) { protected function joinRelationship($conn, $query, $field, $type) {
$fbids = $query->getParameter($field, array()); $phids = $query->getParameter($field, array());
if (!$fbids) { if (!$phids) {
return null; return null;
} }
return qsprintf(
$is_existence = false;
switch ($type) {
case PhabricatorSearchRelationship::RELATIONSHIP_OPEN:
$is_existence = true;
break;
}
$sql = qsprintf(
$conn, $conn,
'relationship AS %C ON %C.fbid = data.fbid AND %C.relation = %s '%T AS %C ON %C.phid = document.phid AND %C.relation = %s',
AND %C.relatedFBID in (%Ld)', id(new PhabricatorSearchDocumentRelationship())->getTableName(),
$field, $field,
$field, $field,
$field, $field,
$type, $type);
if (!$is_existence) {
$sql .= qsprintf(
$conn,
' AND %C.relatedPHID in (%Ls)',
$field, $field,
$fbids); $phids);
}
return $sql;
} }

View file

@ -6,11 +6,15 @@
phutil_require_module('phabricator', 'applications/search/constants/relationship');
phutil_require_module('phabricator', 'applications/search/execute/base'); phutil_require_module('phabricator', 'applications/search/execute/base');
phutil_require_module('phabricator', 'applications/search/storage/document/document'); phutil_require_module('phabricator', 'applications/search/storage/document/document');
phutil_require_module('phabricator', 'applications/search/storage/document/field'); phutil_require_module('phabricator', 'applications/search/storage/document/field');
phutil_require_module('phabricator', 'applications/search/storage/document/relationship');
phutil_require_module('phabricator', 'storage/qsprintf'); phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx'); phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchMySQLExecutor.php'); phutil_require_source('PhabricatorSearchMySQLExecutor.php');

View file

@ -47,8 +47,8 @@ final class PhabricatorSearchAbstractDocument {
return $this; return $this;
} }
public function addRelationship($type, $related_phid) { public function addRelationship($type, $related_phid, $rtype, $time) {
$this->relationships[] = array($type, $related_phid); $this->relationships[] = array($type, $related_phid, $rtype, $time);
return $this; return $this;
} }

View file

@ -36,7 +36,9 @@ class PhabricatorSearchDifferentialIndexer
$doc->addRelationship( $doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
$rev->getAuthorPHID()); $rev->getAuthorPHID(),
'USER',
$rev->getDateCreated());
PhabricatorSearchDocument::reindexAbstractDocument($doc); PhabricatorSearchDocument::reindexAbstractDocument($doc);
} }

View file

@ -33,7 +33,87 @@ class PhabricatorSearchManiphestIndexer
$doc->addRelationship( $doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
$task->getAuthorPHID()); $task->getAuthorPHID(),
'USER',
$task->getDateCreated());
if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$task->getPHID(),
'TASK',
time());
}
$transactions = id(new ManiphestTransaction())->loadAllWhere(
'taskID = %d',
$task->getID());
$current_ccs = $task->getCCPHIDs();
$touches = array();
$owner = null;
$ccs = array();
foreach ($transactions as $transaction) {
if ($transaction->hasComments()) {
$doc->addField(
PhabricatorSearchField::FIELD_COMMENT,
$transaction->getComments());
}
$author = $transaction->getAuthorPHID();
// Record the most recent time they touched this object.
$touches[$author] = $transaction->getDateCreated();
switch ($transaction->getTransactionType()) {
case ManiphestTransactionType::TYPE_OWNER:
$owner = $transaction;
break;
case ManiphestTransactionType::TYPE_CCS:
// For users who are still CC'd, record the first time they were
// added to CC.
foreach ($transaction->getNewValue() as $added_cc) {
if (in_array($added_cc, $current_ccs)) {
if (empty($ccs[$added_cc])) {
$ccs[$added_cc] = $transaction->getDateCreated();
// CCs count as touches, even if you didn't technically
// interact with the object directly.
$touches[$added_cc] = $transaction->getDateCreated();
}
}
}
break;
}
}
if ($owner && $owner->getNewValue()) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
$owner->getNewValue(),
'USER',
$owner->getDateCreated());
}
foreach ($touches as $touch => $time) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_TOUCH,
$touch,
'USER',
$time);
}
// We need to load handles here since non-users may subscribe (mailing
// lists, e.g.)
$handles = id(new PhabricatorObjectHandleData(array_keys($ccs)))
->loadHandles();
foreach ($ccs as $cc => $time) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
$handles[$cc]->getPHID(),
$handles[$cc]->getType(),
$time);
}
PhabricatorSearchDocument::reindexAbstractDocument($doc); PhabricatorSearchDocument::reindexAbstractDocument($doc);
} }

View file

@ -6,11 +6,17 @@
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/search/constants/field'); phutil_require_module('phabricator', 'applications/search/constants/field');
phutil_require_module('phabricator', 'applications/search/constants/relationship'); phutil_require_module('phabricator', 'applications/search/constants/relationship');
phutil_require_module('phabricator', 'applications/search/index/abstractdocument'); phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
phutil_require_module('phabricator', 'applications/search/index/indexer/base'); phutil_require_module('phabricator', 'applications/search/index/indexer/base');
phutil_require_module('phabricator', 'applications/search/storage/document/document'); phutil_require_module('phabricator', 'applications/search/storage/document/document');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchManiphestIndexer.php'); phutil_require_source('PhabricatorSearchManiphestIndexer.php');

View file

@ -63,10 +63,11 @@ class PhabricatorSearchDocument extends PhabricatorSearchDAO {
list($ftype, $corpus, $aux_phid) = $field; list($ftype, $corpus, $aux_phid) = $field;
queryfx( queryfx(
$conn_w, $conn_w,
'INSERT INTO %T (phid, field, auxPHId, corpus) '. 'INSERT INTO %T (phid, phidType, field, auxPHID, corpus) '.
' VALUES (%s, %s, %ns, %s)', ' VALUES (%s, %s, %s, %ns, %s)',
$field_dao->getTableName(), $field_dao->getTableName(),
$phid, $phid,
$doc->getDocumentType(),
$ftype, $ftype,
$aux_phid, $aux_phid,
$corpus); $corpus);
@ -75,13 +76,15 @@ class PhabricatorSearchDocument extends PhabricatorSearchDAO {
$sql = array(); $sql = array();
foreach ($doc->getRelationshipData() as $relationship) { foreach ($doc->getRelationshipData() as $relationship) {
list($rtype, $toPHID) = $relationship; list($rtype, $to_phid, $to_type, $time) = $relationship;
$sql[] = qsprintf( $sql[] = qsprintf(
$conn_w, $conn_w,
'(%s, %s, %s)', '(%s, %s, %s, %s, %d)',
$phid, $phid,
$toPHID, $to_phid,
$rtype); $rtype,
$to_type,
$time);
} }
$rship_dao = new PhabricatorSearchDocumentRelationship(); $rship_dao = new PhabricatorSearchDocumentRelationship();
@ -93,7 +96,8 @@ class PhabricatorSearchDocument extends PhabricatorSearchDAO {
if ($sql) { if ($sql) {
queryfx( queryfx(
$conn_w, $conn_w,
'INSERT INTO %T (phid, relatedPHID, relation) '. 'INSERT INTO %T'.
' (phid, relatedPHID, relation, relatedType, relatedTime) '.
' VALUES %Q', ' VALUES %Q',
$rship_dao->getTableName(), $rship_dao->getTableName(),
implode(', ', $sql)); implode(', ', $sql));

View file

@ -21,6 +21,8 @@ class PhabricatorSearchDocumentRelationship extends PhabricatorSearchDAO {
protected $phid; protected $phid;
protected $relatedPHID; protected $relatedPHID;
protected $relation; protected $relation;
protected $relatedType;
protected $relatedTime;
public function getConfiguration() { public function getConfiguration() {
return array( return array(

View file

@ -111,6 +111,15 @@ JX.behavior('phabricator-object-selector', function(config) {
e.kill(); e.kill();
sendQuery(); sendQuery();
}); });
JX.DOM.listen(
JX.$(config.search),
'click',
'tag:button',
function(e) {
e.kill();
sendQuery();
});
JX.DOM.listen( JX.DOM.listen(
JX.$(config.results), JX.$(config.results),