mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-02-10 03:29:35 +00:00
More generous search
Split the keyword into tokens (at spaces). Search for every token individually, then combine results with AND.
This commit is contained in:
parent
b8d5b83eee
commit
6b4ff26a63
1 changed files with 44 additions and 16 deletions
|
|
@ -65,11 +65,16 @@ class PartSearchFilter implements FilterInterface
|
|||
/** @var bool Use Internal Part number for searching */
|
||||
protected bool $ipn = true;
|
||||
|
||||
/** @var int Helper variable for hacky array_map variable injection */
|
||||
protected int $it = 0;
|
||||
|
||||
public function __construct(
|
||||
/** @var string The string to query for */
|
||||
protected string $keyword
|
||||
)
|
||||
{
|
||||
// Transform keyword and trim excess spaces
|
||||
$keyword = trim(str_replace('+', ' ', $keyword));
|
||||
}
|
||||
|
||||
protected function getFieldsToSearch(): array
|
||||
|
|
@ -125,26 +130,50 @@ class PartSearchFilter implements FilterInterface
|
|||
return;
|
||||
}
|
||||
|
||||
//Convert the fields to search to a list of expressions
|
||||
$expressions = array_map(function (string $field): string {
|
||||
if ($this->regex) {
|
||||
if($this->regex) {
|
||||
//Convert the fields to search to a list of expressions
|
||||
$expressions = array_map(function (string $field): string {
|
||||
return sprintf("REGEXP(%s, :search_query) = TRUE", $field);
|
||||
}
|
||||
}, $fields_to_search);
|
||||
|
||||
return sprintf("ILIKE(%s, :search_query) = TRUE", $field);
|
||||
}, $fields_to_search);
|
||||
//Add Or concatenation of the expressions to our query
|
||||
$queryBuilder->andWhere(
|
||||
$queryBuilder->expr()->orX(...$expressions)
|
||||
);
|
||||
|
||||
//Add Or concatenation of the expressions to our query
|
||||
$queryBuilder->andWhere(
|
||||
$queryBuilder->expr()->orX(...$expressions)
|
||||
);
|
||||
|
||||
//For regex, we pass the query as is, for like we add % to the start and end as wildcards
|
||||
if ($this->regex) {
|
||||
//For regex, we pass the query as is, save html special chars
|
||||
$queryBuilder->setParameter('search_query', $this->keyword);
|
||||
} else {
|
||||
$queryBuilder->setParameter('search_query', '%' . $this->keyword . '%');
|
||||
return;
|
||||
}
|
||||
|
||||
//Split keyword on spaces, but limit token count to not blow up the DB
|
||||
$tokens = explode(' ', $this->keyword, 5);
|
||||
|
||||
$params = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
|
||||
//Perform search of every single token in every selected field, AND the where clauses
|
||||
for ($i = 0; $i < sizeof($tokens); $i++) {
|
||||
$this->it = $i;
|
||||
$tokens[$i] = trim($tokens[$i]);
|
||||
|
||||
//Skip empty words (e.g. because of multiple spaces)
|
||||
if ($tokens[$i] === '') continue;
|
||||
|
||||
//Convert the fields to search to a list of expressions
|
||||
$expressions = array_map(function (string $field): string {
|
||||
return sprintf("ILIKE(%s, :search_query%u) = TRUE", $field, $this->it);
|
||||
}, $fields_to_search);
|
||||
|
||||
//Aggregate the parameters for consolidated commission
|
||||
$params[] = new \Doctrine\ORM\Query\Parameter('search_query' . $i, '%' . $tokens[$i] . '%');
|
||||
|
||||
//Add Or concatenation of the expressions to our query
|
||||
$queryBuilder->andWhere(
|
||||
$queryBuilder->expr()->orX(...$expressions)
|
||||
);
|
||||
}
|
||||
$queryBuilder->setParameters($params);
|
||||
|
||||
}
|
||||
|
||||
public function getKeyword(): string
|
||||
|
|
@ -301,5 +330,4 @@ class PartSearchFilter implements FilterInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue