[evolvis-commits] r11958: [#2617] Text searching enhancement
mirabilos at evolvis.org
mirabilos at evolvis.org
Thu Feb 24 18:30:49 CET 2011
Author: mirabilos
Date: 2011-02-24 18:30:49 +0100 (Thu, 24 Feb 2011)
New Revision: 11958
Added:
trunk/gforge_base/evolvisforge-5.1/gforge/db/FTI-20061025.sql
Modified:
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ArtifactSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/DocsSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ExportProjectSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ForumSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/FrsSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/NewsSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/PeopleSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ProjectSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SkillSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TasksSearchQuery.class
trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TrackersSearchQuery.class
Log:
[#2617] Text searching enhancement
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ArtifactSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ArtifactSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ArtifactSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -39,6 +39,7 @@
* @param int $artifactId artifact id
*/
function ArtifactSearchQuery($words, $offset, $isExact, $groupId, $artifactId) {
+ //TODO: Why is groupId an arg and var since it isn't used anywhere?
$this->groupId = $groupId;
$this->artifactId = $artifactId;
@@ -55,20 +56,46 @@
if ($sys_use_fti) {
$words=$this->getFormattedWords();
$artifactId = $this->artifactId;
- $sql = "SELECT DISTINCT ON (artifact.artifact_id) artifact.artifact_id,
- artifact.group_artifact_id, artifact.summary AS summary,
- artifact.open_date, users.realname, artifact_group_list.name
- FROM artifact LEFT JOIN artifact_message USING (artifact_id), users,
- artifact_group_list
- WHERE users.user_id = artifact.submitted_by
- AND artifact_group_list.group_artifact_id = artifact.group_artifact_id
- AND artifact_group_list.group_artifact_id='$artifactId'
- AND artifact.artifact_id IN (
- SELECT artifact_id FROM artifact_idx,
- to_tsquery('$words') AS q WHERE vectors @@ q ORDER BY rank(vectors, q) DESC)
- OR artifact.artifact_id IN (
- SELECT artifact_id FROM artifact_message_idx,
- to_tsquery('$words') AS q WHERE vectors @@ q ORDER BY rank(vectors, q) DESC)";
+ if(count($words)) {
+ $tsquery0 = "headline(summary, '".$this->getFormattedWords()."') as summary";
+ $tsquery = ", artifact_idx ai, artifact_message_idx ami, to_tsquery('".$words."') q";
+ $tsmatch = "(ai.vectors @@ q OR ami.vectors @@ q)";
+ $rankCol = "sum((rank(ai.vectors, q)+rank(ami.vectors, q))) as rank";
+ $tsjoin = 'AND ai.artifact_id = a.artifact_id '
+ . 'AND ami.id = am.id ';
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "summary";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "0 as rank";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $detailsCond = $this->getMatchCond('a.details', $this->phrases);
+ $summaryCond = $this->getMatchCond('a.summary', $this->phrases);
+ $msgCond = $this->getMatchCond('am.body', $this->phrases);
+ $phraseCond = "$phraseOp (($detailsCond) OR ($summaryCond))";
+ }
+ $sql = "
+ select a.group_artifact_id,a.artifact_id, $tsquery0,
+ a.open_date,users.realname, rank
+ FROM (SELECT a.artifact_id,
+ $rankCol
+ FROM artifact a LEFT OUTER JOIN artifact_message am USING (artifact_id)
+ $tsquery
+ WHERE
+ a.group_artifact_id='$artifactId'
+ $tsjoin
+ AND ($tsmatch $phraseCond)
+ GROUP BY a.artifact_id) x,
+ artifact a, users
+ WHERE
+ a.artifact_id = x.artifact_id
+ AND users.user_id=a.submitted_by
+ ORDER BY group_artifact_id ASC, rank DESC, a.artifact_id ASC";
} else {
$sql = 'SELECT DISTINCT ON (a.group_artifact_id,a.artifact_id) a.group_artifact_id,a.artifact_id,a.summary,a.open_date,users.realname '
. 'FROM artifact a LEFT OUTER JOIN artifact_message am USING (artifact_id), users '
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/DocsSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/DocsSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/DocsSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -88,16 +88,40 @@
}
$words = $this->getFormattedWords();
$group_id=$this->groupId;
+
+ if(count($this->words)) {
+ $tsquery0 = "headline(doc_data.title, q) AS title, headline(doc_data.description, q) AS description";
+ $tsquery = ", doc_data_idx, to_tsquery('".$words()."') q";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND doc_data.docid = doc_data_idx.docid ';
+ $orderBy = "ORDER BY rank(vectors, q) DESC, groupname ASC";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "title, description";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY groupname";
+ $phraseOp = "";
+ }
+
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $titleCond = $this->getMatchCond('title', $this->phrases);
+ $descCond = $this->getMatchCond('description', $this->phrases);
+ $phraseCond = $phraseOp.' (('.$titleCond.') OR ('.$descCond.'))';
+ }
- $sql="SELECT doc_data.docid, headline(doc_data.title, q) AS title,
- headline(doc_data.description, q) AS description, doc_groups.groupname
- FROM doc_data, doc_groups, to_tsquery('$words') AS q, doc_data_idx
- WHERE doc_data.doc_group = doc_groups.doc_group
- AND doc_data.docid = doc_data_idx.docid AND vectors @@ q
- AND doc_data.group_id = '$group_id'
- $sections
- AND doc_data.stateid IN ($nonPublic)
- ORDER BY rank(vectors, q) DESC";
+ $sql="SELECT doc_data.docid, $tsquery0, doc_groups.groupname
+ FROM doc_data, doc_groups $tsquery
+ WHERE doc_data.doc_group = doc_groups.doc_group
+ $tsjoin AND ($tsmatch $phraseCond )
+ AND doc_data.group_id = '$group_id'
+ $sections
+ AND doc_data.stateid IN ($nonPublic)
+ $orderBy";
return $sql;
}
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ExportProjectSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ExportProjectSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ExportProjectSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -35,13 +35,39 @@
global $sys_use_fti;
if ($sys_use_fti) {
$words = $this->getFormattedWords();
- $sql = "SELECT headline(group_name, q) as group_name,
- headline(unix_group_name, q) as unix_group_name,
- type_id,groups.group_id,headline(short_description, q) as short_description,
- license,register_time FROM groups, to_tsquery('$words') AS q, groups_idx
- WHERE groups.group_id = groups_idx.group_id AND vectors @@ q AND
- status IN ('A', 'H') AND is_public='1' AND short_description <> ''
- ORDER BY rank(vectors, q) DESC";
+ if(count($this->words)) {
+ $tsquery0 = "headline(unix_group_name, q) as unix_group_name, headline(short_description, q) as short_description";
+ $tsquery = ", groups_idx, to_tsquery('".$words."') q";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND groups.group_id = groups_idx.group_id ';
+ $orderBy = "ORDER BY rank(vectors, q) DESC, group_name ASC";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "unix_group_name, short_description";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY group_name";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $groupNameCond = $this->getMatchCond('group_name', $this->phrases);
+ $groupDescriptionCond = $this->getMatchCond('short_description', $this->phrases);
+ $groupUnixNameCond = $this->getMatchCond('unix_group_name', $this->phrases);
+ $phraseCond = $phraseOp.' (('.$groupNameCond.') OR ('.$groupDescriptionCond.') OR ('.$groupUnixNameCond.'))';
+ }
+ $sql = "SELECT $tsquery0,
+ type_id,
+ groups.group_id,
+ license,
+ register_time
+ FROM groups $tsquery
+ WHERE status IN ('A', 'H') AND is_public='1' AND short_description <> ''
+ $tsjoin AND ($tsmatch $phraseCond)
+ $orderBy";
} else {
$groupNameCond = $this->getIlikeCondition('group_name', $this->words);
$groupDescriptionCond = $this->getIlikeCondition('short_description', $this->words);
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ForumSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ForumSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ForumSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -54,11 +54,36 @@
global $sys_use_fti;
if ($sys_use_fti) {
$words = $this->getFormattedWords();
- $sql = "SELECT forum.msg_id, headline(forum.subject, q) AS subject, forum.post_date, users.realname "
- ." FROM forum, users, to_tsquery('$words') AS q, forum_idx as fi "
- ." WHERE fi.msg_id = forum.msg_id AND vectors @@ q "
- ." AND users.user_id=forum.posted_by AND forum.group_forum_id=$this->forumId "
- ." ORDER BY rank(vectors, q) DESC";
+ if(count($this->words)) {
+ $tsquery0 = "headline(forum.subject, q) AS subject";
+ $tsquery = ", to_tsquery('".$words."') AS q, forum_idx as fi";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND fi.msg_id = forum.msg_id';
+ $orderBy = "ORDER BY rank(vectors, q) DESC";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "subject";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY post_date DESC";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $bodyCond = $this->getMatchCond('forum.body', $this->phrases);
+ $subjectCond = $this->getMatchCond('forum.subject', $this->phrases);
+ $phraseCond = $phraseOp.' (('.$bodyCond.') OR ('.$subjectCond.'))';
+ }
+ $sql = "SELECT forum.msg_id, $tsquery0, forum.post_date, users.realname
+ FROM forum, users $tsquery
+ WHERE
+ forum.group_forum_id =".$this->forumId."
+ AND forum.posted_by = users.user_id
+ $tsjoin AND ($tsmatch $phraseCond)
+ $orderBy";
} else {
$sql = 'SELECT forum.msg_id, forum.subject, forum.post_date, users.realname '
. 'FROM forum,users '
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/FrsSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/FrsSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/FrsSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -53,15 +53,46 @@
function getQuery() {
global $sys_use_fti;
if ($sys_use_fti) {
- $nonPublic = 'false';
- $sections = '';
- if ($this->showNonPublic) {
- $nonPublic = 'true';
+ if(count($this->words)) {
+ $tsquery0 = "headline(frs_package.name, q) AS package_name, headline(frs_release.name, q) as release_name";
+ $tsquery = ", to_tsquery('".$this->getFormattedWords()."') AS q, frs_release_idx r, frs_file_idx f";
+ $tsmatch = "(f.vectors @@ q OR r.vectors @@ q)";
+ $rankCol = "";
+ $tsjoin = 'AND r.release_id = frs_release.release_id AND f.file_id = frs_file.file_id';
+ $orderBy = "ORDER BY frs_package.name, frs_release.name";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "frs_package.name as package_name, frs_release.name as release_name";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY frs_package.name, frs_release.name";
+ $phraseOp = "";
}
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $phraseCond .= $phraseOp.'(('.$this->getMatchCond('frs_release.changes', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('frs_release.notes', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('frs_release.name', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('frs_file.filename', $this->phrases).'))';
+ }
+ $sql = 'SELECT '.$tsquery0.', frs_release.release_date, frs_release.release_id, users.realname'
+ . ' FROM frs_file, frs_release, users, frs_package'.$tsquery
+ . ' WHERE frs_release.released_by = users.user_id'
+ . $tsjoin
+ . ' AND frs_package.package_id = frs_release.package_id'
+ . ' AND frs_file.release_id=frs_release.release_id'
+ . ' AND frs_package.group_id='.$this->groupId;
if ($this->sections != SEARCH__ALL_SECTIONS) {
$sections = $this->sections;
+ $sql .= ' AND frs_package.package_id IN ('.$this->sections.') ';
}
- $sql = "SELECT * FROM frs_search('".$this->getFormattedWords()."', ".$this->groupId.", '$sections', $nonPublic)";
+ if(!$this->showNonPublic) {
+ $sql .= ' AND is_public=1';
+ }
+
+ $sql .= ' AND ( '.$tsmatch.' '.$phraseCond.') '.$orderBy;
} else {
$sql = 'SELECT frs_package.name as package_name, frs_release.name as release_name, frs_release.release_date, frs_release.release_id, users.realname'
. ' FROM frs_file, frs_release, users, frs_package'
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/NewsSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/NewsSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/NewsSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -42,18 +42,41 @@
function getQuery() {
global $sys_use_fti;
if ($sys_use_fti) {
- $words = $this->getFormattedWords();
$group_id=$this->groupId;
- $sql = "SELECT headline(news_bytes.summary, q) as summary,
+ if(count($this->words)) {
+ $tsquery0 = "headline(news_bytes.summary, q) as summary";
+ $words = $this->getFormattedWords();
+ $tsquery = ", to_tsquery('$words') AS q, news_bytes_idx";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND news_bytes_idx.id = news_bytes.id';
+ $orderBy = "ORDER BY rank(vectors, q) DESC, post_date DESC";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "summary";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY post_date DESC";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $phraseCond .= $phraseOp.'('
+ . ' ('.$this->getMatchCond('summary', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('details', $this->phrases).'))';
+ }
+ $sql = "SELECT $tsquery0,
news_bytes.post_date,
news_bytes.forum_id,
users.realname
- FROM news_bytes, users, to_tsquery('$words') AS q, news_bytes_idx
+ FROM news_bytes, users $tsquery
WHERE (news_bytes.group_id='$group_id' AND news_bytes.is_approved <> '4'
- AND news_bytes_idx.id = news_bytes.id
+ $tsjoin
AND news_bytes.submitted_by=users.user_id) AND
- (vectors @@ q)
- ORDER BY rank(vectors, q) DESC";
+ ($tsmatch $phraseCond)
+ $orderBy";
} else {
$sql = 'SELECT news_bytes.summary, news_bytes.post_date, news_bytes.forum_id, users.realname'
. ' FROM news_bytes, users'
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/PeopleSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/PeopleSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/PeopleSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -34,7 +34,36 @@
function getQuery() {
global $sys_use_fti;
if ($sys_use_fti) {
- $sql = "SELECT * FROM users_search('".$this->getFormattedWords()."')";
+ if(count($this->words)) {
+ $tsquery0 = ", user_name, headline(realname, q) as realname ";
+ $words = $this->getFormattedWords();
+ $tsquery = ", to_tsquery('$words') AS q, users_idx ";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND users_idx.user_id = users.user_id';
+ $orderBy = "ORDER BY rank(vectors, q) DESC, user_name";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = ", user_name, realname ";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY user_name";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $phraseCond .= $phraseOp.'('
+ . ' ('.$this->getMatchCond('user_name', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('realname', $this->phrases).'))';
+ }
+ $sql = 'SELECT users.user_id '.$tsquery0
+ . 'FROM users '.$tsquery
+ . 'WHERE (status=\'A\') '
+ . $tsjoin
+ . " AND ($tsmatch $phraseCond) "
+ . $orderBy;
} else {
$sql = 'SELECT user_name,user_id,realname '
. 'FROM users '
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ProjectSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ProjectSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/ProjectSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -34,7 +34,38 @@
function getQuery() {
global $sys_use_fti;
if ($sys_use_fti) {
- $sql = "SELECT * FROM groups_search('".$this->getFormattedWords()."')";
+ if(count($this->words)) {
+ $tsquery0 = "headline(group_name, q) as group_name, " .
+ "unix_group_name, " .
+ "headline(short_description, q) as short_description";
+ $words = $this->getFormattedWords();
+ $tsquery = ", to_tsquery('$words') AS q, groups_idx as i ";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND g.group_id = i.group_id';
+ $distinctOn = "rank(vectors, q), group_name";
+ $orderBy = "ORDER BY rank(vectors, q) DESC, group_name";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "group_name, unix_group_name, short_description";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $distinctOn = "group_name";
+ $orderBy = "ORDER BY group_name";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $groupNameCond = $this->getMatchCond('group_name', $this->phrases);
+ $groupDescriptionCond = $this->getMatchCond('short_description', $this->phrases);
+ $groupUnixNameCond = $this->getMatchCond('unix_group_name', $this->phrases);
+ $phraseCond = $phraseOp.' (('.$groupNameCond.') OR ('.$groupDescriptionCond.') OR ('.$groupUnixNameCond.'))';
+ }
+ $sql = "SELECT DISTINCT ON ($distinctOn) type_id, g.group_id, " .$tsquery0.
+ " FROM groups AS g ".$tsquery.
+ " WHERE g.status in ('A', 'H') AND ($tsmatch $phraseCond) $tsjoin $orderBy";
} else {
$groupNameCond = $this->getIlikeCondition('group_name', $this->words);
$groupDescriptionCond = $this->getIlikeCondition('short_description', $this->words);
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -67,6 +67,10 @@
*/
var $sections = SEARCH__ALL_SECTIONS;
+ var $words;
+
+ var $phrases;
+
/**
* Constructor
*
@@ -105,7 +109,38 @@
$this->setError('error_search_minlength');
return;
}
- $this->words = explode(' ', quotemeta($words));
+ $this->words = array();
+ $this->phrases = array();
+ $phrase = '';
+ $inQuote = false;
+ foreach(explode(' ', quotemeta($words)) as $word) {
+ if($inQuote) {
+ if(substr($word, -3) == "\\\\'") {
+ $word = substr($word, 0, -3);
+ $inQuote = false;
+ $phrase .= ' '.$word;
+ $this->phrases[] = $phrase;
+ } else {
+ $phrase .= ' '.$word;
+ }
+ } else {
+ if(substr($word, 0, 3) == "\\\\'") {
+ $word = substr($word, 3);
+ $inQuote = true;
+ if(substr($word, -3) == "\\\\'") {
+ // This is a special case where the phrase is just one word
+ $word = substr($word, 0, -3);
+ $inQuote = false;
+ $this->phrases[] = $word;
+ } else {
+ $phrase = $word;
+ }
+ } else {
+ $this->words[] = $word;
+ }
+ }
+
+ }
}
}
@@ -151,8 +186,19 @@
* @return string the condition
*/
function getIlikeCondition($fieldName) {
- return $fieldName." ILIKE '%" . implode("%' ".$this->operator." ".$fieldName." ILIKE '%", $this->words) ."%'";
+ $wordArgs = array_merge($this->words, str_replace(' ', "\\\s+",$this->phrases));
+ return $fieldName." ILIKE '%" . implode("%' ".$this->operator." ".$fieldName." ILIKE '%", $wordArgs) ."%'";
}
+
+ function getMatchCond($fieldName, $arr) {
+ if(!count($arr)) {
+ $result = 'TRUE';
+ } else {
+ $regexs = str_replace(' ', "\\\s+",$arr);
+ $result = $fieldName." ~* '" . implode("' ".$this->operator." ".$fieldName." ~* '", $regexs) ."'";
+ }
+ return $result;
+ }
/**
* getOperator - get the operator we have to use in ILIKE condition
@@ -257,7 +303,6 @@
} else {
$words = implode('|', $this->words);
}
- return $words;
}
}
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SkillSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SkillSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/SkillSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -33,13 +33,40 @@
*/
function getQuery() {
global $sys_use_fti;
- $words = $this->getFormattedWords();
- if ($sys_use_fti) {
- $sql = "SELECT skills_data.skills_data_id, skills_data.type, headline(skills_data.title, q) as title,
- skills_data.start,skills_data.finish,headline(skills_data.keywords, q) as keywords
- FROM skills_data, to_tsquery('$words') AS q, users, skills_data_types, skills_data_idx
- WHERE skills_data.user_id=users.user_id AND skills_data.skills_data_id = skills_data_idx.skills_data_id
- AND skills_data.type=skills_data_types.type_id AND (vectors @@ q) ORDER BY rank(vectors, q) DESC";
+ if ($sys_use_fti) {
+ if(count($this->words)) {
+ $words = $this->getFormattedWords();
+ $tsquery0 = "headline(skills_data.title, q) as title, headline(skills_data.keywords, q) as keywords ";
+ $tsquery = ", to_tsquery('$words') AS q, skills_data_idx";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = 'AND skills_data.skills_data_id = skills_data_idx.skills_data_id ';
+ $orderBy = "ORDER BY rank(vectors, q) DESC, finish DESC";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "title, keywords ";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY finish DESC";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $phraseCond .= $phraseOp.'('
+ . ' ('.$this->getMatchCond('skills_data.title', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('skills_data.keywords', $this->phrases).'))';
+ }
+ $sql = 'SELECT skills_data.skills_data_id, skills_data.type, '
+ . 'skills_data.start, skills_data.finish, '.$tsquery0
+ . 'FROM skills_data, users, skills_data_types '
+ . $tsquery
+ . ' WHERE (vectors @@ q '.$phraseCond.') '
+ . $tsjoin
+ . 'AND (skills_data.user_id=users.user_id) '
+ . 'AND (skills_data.type=skills_data_types.type_id) '
+ . $orderBy;
} else {
$sql = 'SELECT * '
. 'FROM skills_data, users, skills_data_types '
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TasksSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TasksSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TasksSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -54,12 +54,37 @@
function getQuery() {
global $sys_use_fti;
if ($sys_use_fti) {
- $sql = 'SELECT project_task.project_task_id,headline(project_task.summary, q) AS summary,project_task.percent_complete,'
+ if(count($this->words)) {
+ $tsquery0 = "headline(project_task.summary, q) AS summary,";
+ $words = $this->getFormattedWords();
+ $tsquery = ", to_tsquery('$words') AS q, project_task_idx";
+ $tsmatch = "vectors @@ q";
+ $rankCol = "";
+ $tsjoin = ' AND project_task.project_task_id = project_task_idx.project_task_id';
+ $orderBy = "ORDER BY project_group_list.project_name, rank(vectors, q) DESC, project_task.project_task_id";
+ $phraseOp = $this->getOperator();
+ } else {
+ $tsquery0 = "summary, ";
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "ORDER BY project_group_list.project_name, project_task.project_task_id";
+ $phraseOp = "";
+ }
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $phraseCond .= $phraseOp.'('
+ . ' ('.$this->getMatchCond('summary', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('details', $this->phrases).'))';
+ }
+ $sql = 'SELECT project_task.project_task_id,project_task.percent_complete,'
+ . $tsquery0
. ' project_task.start_date,project_task.end_date,users.firstname||\' \'||users.lastname AS realname, project_group_list.project_name, project_group_list.group_project_id '
- . ' FROM project_task, users, project_group_list, project_task_idx, '
- . ' to_tsquery(\''.$this->getFormattedWords().'\') q'
+ . ' FROM project_task, users, project_group_list '
+ . $tsquery
. ' WHERE project_task.created_by = users.user_id'
- . ' AND project_task.project_task_id = project_task_idx.project_task_id'
+ . $tsjoin
. ' AND project_task.group_project_id = project_group_list.group_project_id '
. ' AND project_group_list.group_id ='.$this->groupId.' ';
if ($this->sections != SEARCH__ALL_SECTIONS) {
@@ -68,8 +93,7 @@
if (!$this->showNonPublic) {
$sql .= 'AND project_group_list.is_public = 1 ';
}
- $sql .= 'AND (vectors @@q)'
- . ' ORDER BY rank(vectors, q) DESC';
+ $sql .= "AND ($tsmatch $phraseCond) $orderBy";
} else {
$sql = 'SELECT project_task.project_task_id,project_task.summary,project_task.percent_complete,'
. ' project_task.start_date,project_task.end_date,users.firstname||\' \'||users.lastname AS realname, project_group_list.project_name, project_group_list.group_project_id '
Modified: trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TrackersSearchQuery.class
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TrackersSearchQuery.class 2011-02-24 17:30:47 UTC (rev 11957)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/common/search/TrackersSearchQuery.class 2011-02-24 17:30:49 UTC (rev 11958)
@@ -54,38 +54,46 @@
function getQuery() {
global $sys_use_fti;
if ($sys_use_fti) {
- $nonPublic = 'false';
- $sections = '';
- if ($this->showNonPublic) {
- $nonPublic = '';
- $nonPublicMsg = '';
+ if(count($this->words)) {
+ $tsquery = ", to_tsquery('".$this->getFormattedWords()."') q, artifact_idx, artifact_message_idx ";
+ $tsmatch = "(artifact_idx.vectors @@ q OR artifact_message_idx.vectors @@ q)";
+ $rankCol = ", (rank(artifact_idx.vectors, q)+rank(artifact_message_idx.vectors, q)) AS rank ";
+ $tsjoin = 'AND artifact_idx.artifact_id = artifact.artifact_id '
+ . 'AND artifact_message_idx.id = artifact_message.id '
+ . 'AND artifact_message_idx.artifact_id = artifact_message_idx.artifact_id ';
+ $orderBy = "ORDER BY RANK DESC";
+ $phraseOp = $this->getOperator();
} else {
- $nonPublic = 'AND artifact_group_list.is_public = 1';
- $nonPublicMsg = 'AND agl.is_public = 1';
+ $tsquery = "";
+ $tsmatch = "";
+ $tsjoin = "";
+ $rankCol = "";
+ $orderBy = "";
+ $phraseOp = "";
}
+ $phraseCond = '';
+ if(count($this->phrases)) {
+ $phraseCond .= $phraseOp.'('
+ . ' ('.$this->getMatchCond('artifact.details', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('artifact.summary', $this->phrases).')'
+ . ' OR ('.$this->getMatchCond('artifact_message.body', $this->phrases).'))';
+ }
+ $sql = 'SELECT artifact.artifact_id, artifact.group_artifact_id, artifact.summary, artifact.open_date, users.realname, artifact_group_list.name '
+ . $rankCol
+ . 'FROM artifact LEFT OUTER JOIN artifact_message USING (artifact_id), users, artifact_group_list '
+ . $tsquery
+ . ' WHERE users.user_id = artifact.submitted_by '
+ . $tsjoin
+ . 'AND artifact_group_list.group_artifact_id = artifact.group_artifact_id '
+ . 'AND artifact_group_list.group_id = '.$this->groupId.' ';
if ($this->sections != SEARCH__ALL_SECTIONS) {
- $sections = "AND artifact_group_list.group_artifact_id IN (".$this->sections.")";
- } else {
- $sections = '';
+ $sql .= 'AND artifact_group_list.group_artifact_id in ('.$this->sections.') ';
}
- $words = $this->getFormattedWords();
- $group_id=$this->groupId;
- $sql = "SELECT DISTINCT ON (artifact.artifact_id) artifact.artifact_id,
- artifact.group_artifact_id, artifact.summary AS summary,
- artifact.open_date, users.realname, artifact_group_list.name
- FROM artifact LEFT JOIN artifact_message USING (artifact_id), users,
- artifact_group_list
- WHERE users.user_id = artifact.submitted_by
- $nonPublic
- AND artifact_group_list.group_artifact_id = artifact.group_artifact_id
- AND artifact_group_list.group_id = '$group_id'
- $sections
- AND artifact.artifact_id IN (
- SELECT artifact_id FROM artifact_idx,
- to_tsquery('$words') AS q WHERE vectors @@ q ORDER BY rank(vectors, q) DESC)
- OR artifact.artifact_id IN (
- SELECT artifact_id FROM artifact_message_idx,
- to_tsquery('$words') AS q WHERE vectors @@ q ORDER BY rank(vectors, q) DESC)";
+ if (!$this->showNonPublic) {
+ $sql .= 'AND artifact_group_list.is_public = 1 ';
+ }
+ $sql .= "AND ($tsmatch $phraseCond)";
+ $sql = "SELECT DISTINCT x.* FROM ($sql) x $orderBy";
} else {
$sql = 'SELECT DISTINCT artifact.artifact_id, artifact.group_artifact_id, artifact.summary, artifact.open_date, users.realname, artifact_group_list.name '
. 'FROM artifact LEFT OUTER JOIN artifact_message USING (artifact_id), users, artifact_group_list '
Added: trunk/gforge_base/evolvisforge-5.1/gforge/db/FTI-20061025.sql
===================================================================
--- trunk/gforge_base/evolvisforge-5.1/gforge/db/FTI-20061025.sql (rev 0)
+++ trunk/gforge_base/evolvisforge-5.1/gforge/db/FTI-20061025.sql 2011-02-24 17:30:49 UTC (rev 11958)
@@ -0,0 +1,7 @@
+DROP FUNCTION export_groups_search(text) CASCADE;
+DROP FUNCTION forum_search(text, integer) CASCADE;
+DROP FUNCTION frs_search(text, integer, text, boolean) CASCADE;
+DROP FUNCTION users_search(text) CASCADE;
+DROP FUNCTION groups_search(text) CASCADE;
+DROP FUNCTION skills_data_search(text) CASCADE;
+DROP FUNCTION project_task_search(text, integer, text, boolean) CASCADE;
More information about the evolvis-commits
mailing list