$clauses = array();
if (CRM_Core_InnoDBIndexer::singleton()->hasDeclaredIndex($tableName, $fullTextFields)) {
$formattedQuery = CRM_Utils_QueryFormatter::singleton()
- ->format($queryText, CRM_Utils_QueryFormatter::LANG_SQL_FTS);
+ ->format($queryText, CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL);
$prefixedFieldNames = array();
foreach ($fullTextFields as $fieldName) {
$prefixedFieldNames[] = "$tableAlias.$fieldName";
}
- $clauses[] = sprintf("MATCH (%s) AGAINST ('%s')",
+ $clauses[] = sprintf("MATCH (%s) AGAINST ('%s' IN BOOLEAN MODE)",
implode(',', $prefixedFieldNames),
$strtolower(CRM_Core_DAO::escapeString($formattedQuery))
);
class CRM_Utils_QueryFormatter {
const LANG_SQL_LIKE = 'like';
const LANG_SQL_FTS = 'fts';
+ const LANG_SQL_FTSBOOL = 'ftsbool';
const LANG_SOLR = 'solr';
/**
case self::LANG_SQL_FTS:
$text = $this->_formatFts($text, $this->mode);
break;
+ case self::LANG_SQL_FTSBOOL:
+ $text = $this->_formatFtsBool($text, $this->mode);
+ break;
case self::LANG_SQL_LIKE:
$text = $this->_formatLike($text, $this->mode);
break;
$text = str_replace('%', '*', $text);
if (empty($text)) {
- $result = '%';
+ $result = '*';
}
elseif (strpos($text, '*') !== FALSE) {
// if user supplies their own wildcards, then don't do any sophisticated changes
- return $text;
+ $result = $text;
}
else {
switch ($mode) {
return $this->dedupeWildcards($result, '%');
}
+ protected function _formatFtsBool($text, $mode) {
+ $result = NULL;
+
+ // normalize user-inputted wildcards
+ $text = str_replace('%', '*', $text);
+
+ if (empty($text)) {
+ $result = '*';
+ }
+ elseif (strpos($text, '*') !== FALSE) {
+ // if user supplies their own wildcards, then don't do any sophisticated changes
+ $result = $this->mapWords($text, '+word');
+ }
+ else {
+ switch ($mode) {
+ case self::MODE_NONE:
+ $result = $this->mapWords($text, '+word');
+ break;
+
+ case self::MODE_PHRASE:
+ $result = '+"' . $text . '"';
+ break;
+
+ case self::MODE_WILDPHRASE:
+ $result = '+"*' . $text . '*"';
+ break;
+
+ case self::MODE_WILDWORDS:
+ $result = $this->mapWords($text, '+*word*');
+ break;
+
+ case self::MODE_WILDWORDS_SUFFIX:
+ $result = $this->mapWords($text, '+word*');
+ break;
+
+ default:
+ $result = NULL;
+ }
+ }
+
+ return $this->dedupeWildcards($result, '%');
+ }
+
protected function _formatLike($text, $mode) {
$result = NULL;
return array(
self::LANG_SOLR,
self::LANG_SQL_FTS,
+ self::LANG_SQL_FTSBOOL,
self::LANG_SQL_LIKE,
);
}
$cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTS, CRM_Utils_QueryFormatter::MODE_WILDWORDS, '*first* *second*');
$cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTS, CRM_Utils_QueryFormatter::MODE_WILDWORDS_SUFFIX, 'first* second*');
+ $cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, CRM_Utils_QueryFormatter::MODE_NONE, '+first +second');
+ $cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, CRM_Utils_QueryFormatter::MODE_PHRASE, '+"first second"');
+ $cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, CRM_Utils_QueryFormatter::MODE_WILDPHRASE, '+"*first second*"');
+ $cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, CRM_Utils_QueryFormatter::MODE_WILDWORDS, '+*first* +*second*');
+ $cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, CRM_Utils_QueryFormatter::MODE_WILDWORDS_SUFFIX, '+first* +second*');
+
$cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SOLR, CRM_Utils_QueryFormatter::MODE_NONE, 'first second');
$cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SOLR, CRM_Utils_QueryFormatter::MODE_PHRASE, '"first second"');
$cases[] = array('first second', CRM_Utils_QueryFormatter::LANG_SOLR, CRM_Utils_QueryFormatter::MODE_WILDPHRASE, '"*first second*"');
// if user supplies wildcards, then ignore mode
foreach (array(CRM_Utils_QueryFormatter::MODE_NONE, CRM_Utils_QueryFormatter::MODE_WILDPHRASE, CRM_Utils_QueryFormatter::MODE_WILDWORDS, CRM_Utils_QueryFormatter::MODE_WILDWORDS_SUFFIX) as $mode) {
- $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SQL_LIKE, $mode, 'first% second');
- $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SQL_FTS, $mode, 'first* second');
- $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SOLR, $mode, 'first* second');
- $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SQL_LIKE, $mode, 'first second%');
- $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SQL_FTS, $mode, 'first second*');
- $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SOLR, $mode, 'first second*');
+ $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SQL_LIKE, $mode, 'first% second');
+ $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SQL_FTS, $mode, 'first* second');
+ $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, $mode, '+first* +second');
+ $cases[] = array('first% second', CRM_Utils_QueryFormatter::LANG_SOLR, $mode, 'first* second');
+ $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SQL_LIKE, $mode, 'first second%');
+ $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SQL_FTS, $mode, 'first second*');
+ $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SQL_FTSBOOL, $mode, '+first +second*');
+ $cases[] = array('first second%', CRM_Utils_QueryFormatter::LANG_SOLR, $mode, 'first second*');
}
return $cases;