From 770c870d22459225b84ade9c7152b801c15c8c46 Mon Sep 17 00:00:00 2001 From: Nick Palmer Date: Sat, 16 Feb 2008 23:22:24 +0000 Subject: Add an option to and search words together instead of or-ing them all. --- index.php | 13 +++-- search_lib.php | 136 +++++++++++++++++++++++++++++++++++++++++---------- templates/search.tpl | 13 ++++- 3 files changed, 131 insertions(+), 31 deletions(-) diff --git a/index.php b/index.php index f898c89..e0f9e1b 100644 --- a/index.php +++ b/index.php @@ -1,6 +1,6 @@ assign('usePart', $_REQUEST['usePart']); $gBitSmarty->assign('searchType', $_REQUEST['usePart'] ? "Using Partial Word Search" : "Using Exact Word Search"); +if( isset( $_REQUEST['useAnd'] ) && $_REQUEST['useAnd']=='on' ) { + $_REQUEST['useAnd']=true; +} else { + $_REQUEST['useAnd']=false; +} +$gBitSmarty->assign('useAnd', $_REQUEST['useAnd']); + // Build the query using words if ((!isset($_REQUEST["words"])) || (empty($_REQUEST["words"]))) { $_REQUEST["words"] = ''; @@ -88,9 +96,6 @@ if ( $_REQUEST['cant'] > 0 ) { LibertyContent::postGetList( $_REQUEST ); $gBitSmarty->assign_by_ref( 'listInfo', $_REQUEST['listInfo'] ); -$partialOnOff = $_REQUEST["usePart"] ? 'checked' : ''; -$gBitSmarty->assign('partialOnOff', $partialOnOff); - // Find search results (build array) $gBitSmarty->assign_by_ref('results', $results); diff --git a/search_lib.php b/search_lib.php index e5bda42..4166be2 100644 --- a/search_lib.php +++ b/search_lib.php @@ -1,6 +1,6 @@ mContentTypes as $contentType ) { - if (( $pParamHash['content_type_guid'] == $contentType["content_type_guid"] or $pParamHash['content_type_guid'] == "" ) // pages ? - and $this->has_permission($contentType["content_type_guid"]) - and ( ! $gBitSystem->getConfig('search_restrict_types') || - $gBitSystem->getConfig('search_pkg_'.$contentType["content_type_guid"]) ) ) { - $allowed[] = $contentType["content_type_guid"]; - } - } + function find_with_or($allowed, $selectSql, $joinSql, $whereSql, $bindVars,&$pParamHash) { + // Putting in the below hack because mssql cannot select distinct on a text blob column. + $qPlaceHolders1 = implode(',', array_fill(0, count($pParamHash['words']), '?')); + $bindVars = array_merge( $pParamHash['words'], $allowed ); + LibertyContent::getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); - if (count($allowed) > 0 && count($pParamHash['words']) > 0) { - // Putting in the below hack because mssql cannot select distinct on a text blob column. - $qPlaceHolders1 = implode(',', array_fill(0, count($pParamHash['words']), '?')); - - $selectSql = ''; - $joinSql = ''; - $whereSql = " AND lc.`content_type_guid` IN (" . implode(',', array_fill(0, count($allowed), '?')) . ") "; - $bindVars = array_merge( $pParamHash['words'], $allowed ); - LibertyContent::getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); - - $query = "SELECT + $query = "SELECT lc.`content_id`, lc.`title`, lc.`format_guid`, @@ -227,12 +210,105 @@ class SearchLib extends BitBase { $ret[] = $res; } return $ret; + } + + function find_with_and($allowed, $selectSql, $joinSql, $whereSql, $bindVars, &$pParamHash) { + // Make a slot for the search word. + $bindVars[0] = NULL; + $bindVars = array_merge( $bindVars, $allowed ); + LibertyContent::getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); + + $ret = array(); + $first = true; + foreach($pParamHash['words'] as $word) { + $query = "SELECT lc.`content_id` AS hash_key, + lc.`content_id`, + lc.`title`, + lc.`format_guid`, + lc.`content_type_guid`, + COALESCE(lch.`hits`,0) AS hits, + lc.`created`, + lc.`last_modified`, + lc.`data`, + si.`i_count` AS relevancy + $selectSql + FROM `" . BIT_DB_PREFIX . "liberty_content` lc + LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) + $joinSql + INNER JOIN `".BIT_DB_PREFIX."search_index` si ON (si.`content_id`=lc.`content_id` AND si.`searchword` = ? ) + WHERE `i_count` > 0 $whereSql + ORDER BY 9 DESC, 5 DESC + "; + $bindVars[0] = $word; + $result = $this->mDb->getAssoc( $query, $bindVars ); + if ($first) { + $ret = $result; + $first = false; + } + else { + $this->mergeResults($ret, $result); + } + } + /* count it */ + $pParamHash['cant'] = count($ret); + + /* Sort it */ + uasort($ret, 'search_relevance_sort'); + + /* slice it */ + $ret = array_slice($ret, $pParamHash['offset'], $pParamHash['offset'] + $pParamHash['max_records']); + + /* Set the hrefs. */ + foreach ($ret as $content_id => $data) { + $ret[$content_id]['href'] = BIT_ROOT_URL . "index.php?content_id=" . $content_id; + } + + return $ret; + } + + function find_exact_generic( &$pParamHash ) { + global $gPage, $gBitSystem, $gLibertySystem, $gBitDbType; + $allowed = array(); + $ret = array(); + foreach( $gLibertySystem->mContentTypes as $contentType ) { + if (( $pParamHash['content_type_guid'] == $contentType["content_type_guid"] or $pParamHash['content_type_guid'] == "" ) // pages ? + and $this->has_permission($contentType["content_type_guid"]) + and ( ! $gBitSystem->getConfig('search_restrict_types') || + $gBitSystem->getConfig('search_pkg_'.$contentType["content_type_guid"]) ) ) { + $allowed[] = $contentType["content_type_guid"]; + } + } + + if (count($allowed) > 0 && count($pParamHash['words']) > 0) { + $selectSql = ''; + $joinSql = ''; + $whereSql = " AND lc.`content_type_guid` IN (" . implode(',', array_fill(0, count($allowed), '?')) . ") "; + $bindVars = array(); + + if (isset($pParamHash['useAnd']) && $pParamHash['useAnd']) { + return $this->find_with_and($allowed, $selectSql, $joinSql, $whereSql, $bindVars, $pParamHash); + } + else { + return $this->find_with_or($allowed, $selectSql, $joinSql, $whereSql, $bindVars, $pParamHash); + } } else { $pParamHash['cant'] = 0; return array(); } } + function mergeResults(&$ret, $result) { + // Remove those that don't overlap or update relevance + foreach ($ret as $content_id => $data) { + if (!isset($result[$content_id])) { + unset($ret[$content_id]); + } + else { + $ret[$content_id]['relevancy'] += $result[$content_id]['relevancy']; + } + } + } + function has_permission($pContentType = NULL) { global $gBitUser, $gLibertySystem; @@ -251,4 +327,14 @@ class SearchLib extends BitBase { } # class SearchLib +if (!defined('search_relevance_sort')) { + function search_relevance_sort($a, $b) { + $rel = $b['relevancy'] - $a['relevancy']; + if ($rel == 0) { + $rel = $b['hits'] - $a['hits']; + } + return $rel; + } +} + ?> diff --git a/templates/search.tpl b/templates/search.tpl index 0e4e1f3..4e3606d 100644 --- a/templates/search.tpl +++ b/templates/search.tpl @@ -17,7 +17,16 @@
{formlabel label="Use Partial Word Search" for="usePart"} {forminput} - + + {formhelp note="This may slow search results"} + {/forminput} +
+ + +
+ {formlabel label="And Terms Together" for="useAnd"} + {forminput} + {formhelp note="This may slow search results"} {/forminput}
@@ -68,7 +77,7 @@ {if $words}
{tr}No pages matched the search criteria{/tr}
{/if} {/section} - {pagination usePart=$partialOnOff content_type_guid=$content_type_guid highlight=$words|escape } + {pagination useAnd=$useAnd usePart=$usePart content_type_guid=$content_type_guid highlight=$words|escape } {/strip} -- cgit v1.3