From d662a9c250ff491111d8b845e40b52bbd3afc9ec Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 1 Sep 2015 22:20:07 +0200 Subject: [PATCH] Improved search engine for numeric search queries --- Controller/AdminController.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Controller/AdminController.php b/Controller/AdminController.php index 73db13cdbf..74fc9dcd83 100644 --- a/Controller/AdminController.php +++ b/Controller/AdminController.php @@ -507,21 +507,27 @@ protected function findAll($entityClass, $page = 1, $maxPerPage = 15, $sortField */ protected function findBy($entityClass, $searchQuery, array $searchableFields, $page = 1, $maxPerPage = 15) { - $dbIsPostgreSql = $this->isPostgreSqlUsedByEntity($entityClass); + $databaseIsPostgreSql = $this->isPostgreSqlUsedByEntity($entityClass); $queryBuilder = $this->em->createQueryBuilder()->select('entity')->from($entityClass, 'entity'); $queryConditions = $queryBuilder->expr()->orX(); $queryParameters = array(); foreach ($searchableFields as $name => $metadata) { - // PostgreSQL doesn't allow to compare strings values with non-string columns (e.g. 'id') - if ($dbIsPostgreSql && !in_array($metadata['type'], array('text', 'string'))) { - continue; - } - - if (in_array($metadata['dataType'], array('text', 'string'))) { - $queryConditions->add(sprintf('entity.%s LIKE :query', $name)); - $queryParameters['query'] = '%'.$searchQuery.'%'; + $isNumericField = in_array($metadata['dataType'], array('integer', 'number', 'smallint', 'bigint', 'decimal', 'float')); + $isTextField = in_array($metadata['dataType'], array('string', 'text', 'guid')); + + if (is_numeric($searchQuery) && $isNumericField) { + $queryConditions->add(sprintf('entity.%s = :exact_query', $name)); + $queryParameters['exact_query'] = 0 + $searchQuery; // adding '0' turns the string into a numeric value + } elseif ($isTextField) { + $queryConditions->add(sprintf('entity.%s LIKE :fuzzy_query', $name)); + $queryParameters['fuzzy_query'] = '%'.$searchQuery.'%'; } else { + // PostgreSQL doesn't allow to compare string values with non-string columns (e.g. 'id') + if ($databaseIsPostgreSql) { + continue; + } + $queryConditions->add(sprintf('entity.%s IN (:words)', $name)); $queryParameters['words'] = explode(' ', $searchQuery); }