orm query: supporting match

This commit is contained in:
yuri
2018-06-19 15:35:30 +03:00
parent 9be9ff3d68
commit cd7ca31212
3 changed files with 113 additions and 3 deletions
+60 -1
View File
@@ -107,6 +107,14 @@ abstract class Base
'LENGTH'
];
protected $matchFunctionList = ['MATCH_BOOLEAN', 'MATCH_NATURAL_LANGUAGE', 'MATCH_QUERY_EXPANSION'];
protected $matchFunctionMap = [
'MATCH_BOOLEAN' => 'IN BOOLEAN MODE',
'MATCH_NATURAL_LANGUAGE' => 'IN NATURAL LANGUAGE MODE',
'MATCH_QUERY_EXPANSION' => 'WITH QUERY EXPANSION'
];
protected $entityFactory;
protected $pdo;
@@ -308,6 +316,43 @@ abstract class Base
return $function . '(' . $part . ')';
}
protected function convertMatchExpression($entity, $expression)
{
$delimiterPosition = strpos($expression, ':');
if ($delimiterPosition === false) {
throw new \Exception("Bad MATCH usage.");
}
$function = substr($expression, 0, $delimiterPosition);
$rest = substr($expression, $delimiterPosition + 1);
if (empty($rest)) {
throw new \Exception("Empty MATCH parameters.");
}
$delimiterPosition = strpos($rest, ':');
if ($delimiterPosition === false) {
throw new \Exception("Bad MATCH usage.");
}
$columns = substr($rest, 0, $delimiterPosition);
$query = substr($rest, $delimiterPosition + 1);
$columnList = explode(',', $columns);
foreach ($columnList as $i => $column) {
$columnList[$i] = $this->sanitize($column);
}
$query = $this->quote($query);
if (!in_array($function, $this->matchFunctionList)) return;
$modePart = ' ' . $this->matchFunctionMap[$function];
$result = "MATCH (" . implode(',', $columnList) . ") AGAINST (" . $query . "" . $modePart . ")";
return $result;
}
protected function convertComplexExpression($entity, $field, $distinct = false)
{
@@ -317,7 +362,14 @@ abstract class Base
$entityType = $entity->getEntityType();
if (strpos($field, ':')) {
list($function, $field) = explode(':', $field);
$dilimeterPosition = strpos($field, ':');
$function = substr($field, 0, $dilimeterPosition);
if (in_array($function, $this->matchFunctionList)) {
return $this->convertMatchExpression($entity, $field);
}
$field = substr($field, $dilimeterPosition + 1);
}
if (!empty($function)) {
$function = preg_replace('/[^A-Za-z0-9_]+/', '', $function);
@@ -724,6 +776,13 @@ abstract class Base
foreach ($whereClause as $field => $value) {
if (is_int($field)) {
if (is_string($value)) {
if (strpos($value, 'MATCH_') === 0) {
$rightPart = $this->convertMatchExpression($entity, $value);
$whereParts[] = $rightPart;
continue;
}
}
$field = 'AND';
}
+53
View File
@@ -442,4 +442,57 @@ class QueryTest extends \PHPUnit\Framework\TestCase
"HAVING COUNT(comment.id) > '1'";
$this->assertEquals($expectedSql, $sql);
}
public function testMatch1()
{
$sql = $this->query->createSelectQuery('Article', array(
'select' => ['id', 'name'],
'whereClause' => [
'MATCH_BOOLEAN:name,description:test +hello',
'id!=' => null
]
));
$expectedSql =
"SELECT article.id AS `id`, article.name AS `name` FROM `article` " .
"WHERE MATCH (name,description) AGAINST ('test +hello' IN BOOLEAN MODE) AND article.id IS NOT NULL AND article.deleted = '0'";
$this->assertEquals($expectedSql, $sql);
}
public function testMatch2()
{
$sql = $this->query->createSelectQuery('Article', array(
'select' => ['id', 'name'],
'whereClause' => [
'MATCH_NATURAL_LANGUAGE:description:"test hello"'
]
));
$expectedSql =
"SELECT article.id AS `id`, article.name AS `name` FROM `article` " .
"WHERE MATCH (description) AGAINST ('\"test hello\"' IN NATURAL LANGUAGE MODE) AND article.deleted = '0'";
$this->assertEquals($expectedSql, $sql);
}
public function testMatch3()
{
$sql = $this->query->createSelectQuery('Article', array(
'select' => ['id', 'MATCH_BOOLEAN:description:test'],
'whereClause' => [
'MATCH_BOOLEAN:description:test'
],
'orderBy' => [
[2, 'DESC']
]
));
$expectedSql =
"SELECT article.id AS `id`, MATCH (description) AGAINST ('test' IN BOOLEAN MODE) AS `MATCH_BOOLEAN:description:test` FROM `article` " .
"WHERE MATCH (description) AGAINST ('test' IN BOOLEAN MODE) AND article.deleted = '0' " .
"ORDER BY 2 DESC";
$this->assertEquals($expectedSql, $sql);
}
}
-2
View File
@@ -242,5 +242,3 @@ class Article extends TEntity
)
);
}