Skip to content

Commit

Permalink
Allow filtering to work in the CP (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmitchell authored Jan 27, 2025
2 parents a9b4917 + 39f8564 commit 96b54bd
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/Typesense/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ public function getOrCreateIndex()
return $collection;
}

public function getTypesenseSchemaFields(): Collection
{
return collect(Arr::get($this->getOrCreateIndex()->retrieve(), 'fields', []))
->pluck('type', 'name');
}

private function getDefaultFields(Searchable $entry): array
{
return [
Expand Down
83 changes: 82 additions & 1 deletion src/Typesense/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,90 @@ public function whereStatus($string)
return $this->where('status', $string);
}

private function wheresToFilter(array $wheres): string
{
$filterBy = '';

$schemaFields = $this->index->getTypesenseSchemaFields();

foreach ($this->wheres as $where) {
if ($filterBy != '') {
$filterBy .= $where['boolean'] == 'and' ? ' && ' : ' || ';
}

if ($where['type'] == 'Nested') {
$filterBy .= ' ( '.$this->wheresToFilter($where->query['wheres']).' ) ';

continue;
}

// if its not in our typesense schema, we cant filter on it
if (! $schemaType = $schemaFields->get($where['column'])) {
continue;
}

$filterBy .= ' ( ';

switch ($where['type']) {
case 'JsonContains':
case 'JsonOverlaps':
case 'WhereIn':
$filterBy .= $where['column'].':'.$this->transformArrayOfValuesForTypeSense($schemaType, $where['values']);
break;

case 'JsonDoesnContain':
case 'JsonDoesntOverlap':
case 'WhereNotIn':
$filterBy .= $where['column'].':!='.$this->transformArrayOfValuesForTypeSense($schemaType, $where['values']);
break;

default:
if ($where['operator'] == 'like') {
$where['value'] = str_replace(['%"', '"%'], '', $where['value']);
}

$filterBy .= $where['column'].':'.(! in_array($where['operator'], ['like']) ? $where['operator'] : '').$this->transformValueForTypeSense($schemaType, $where['value']);
break;
}

$filterBy .= ' ) ';

}

return $filterBy;
}

private function transformArrayOfValuesForTypeSense(string $schemaType, array $values): string
{
return json_encode(
collect($values)
->map(fn ($value) => $this->transformValueForTypeSense($schemaType, $value))
->values()
->all()
);
}

private function transformValueForTypeSense(string $schemaType, mixed $value): mixed
{
return match (str_replace('[]', '', $schemaType)) {
'int32', 'int64' => (int) $value,
'float' => (float) $value,
'bool' => $value ? 'true' : 'false',
default => '`'.$value.'`'
};
}

private function getApiResults()
{
return $this->index->searchUsingApi($this->query ?? '', ['per_page' => $this->perPage, 'page' => $this->page]);
$options = ['per_page' => $this->perPage, 'page' => $this->page];

$filterBy = $this->wheresToFilter($this->wheres);

if ($filterBy) {
$options['filter_by'] = $filterBy;
}

return $this->index->searchUsingApi($this->query ?? '', $options);
}

public function forPage($page, $perPage = null)
Expand Down

0 comments on commit 96b54bd

Please sign in to comment.