Skip to content

Commit

Permalink
Add basic filter greaterthan and lessthan, equal and unequal
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-schranz committed Feb 1, 2023
1 parent ad27512 commit 1ce0539
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 26 deletions.
60 changes: 38 additions & 22 deletions packages/seal-solr-adapter/SolrConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
use Schranz\Search\SEAL\Task\SyncTask;
use Solarium\Client;
use Schranz\Search\SEAL\Adapter\ConnectionInterface;
use Schranz\Search\SEAL\Marshaller\Marshaller;
use Schranz\Search\SEAL\Schema\Index;
use Schranz\Search\SEAL\Search\Condition;
use Schranz\Search\SEAL\Search\Result;
use Schranz\Search\SEAL\Search\Search;
use Schranz\Search\SEAL\Task\AsyncTask;
use Schranz\Search\SEAL\Task\TaskInterface;

final class SolrConnection implements ConnectionInterface
Expand Down Expand Up @@ -95,7 +93,7 @@ public function search(Search $search): Result
}

return new Result(
$this->hitsToDocuments($search->indexes, [$result->getDocument()->getFields()]),
$this->hitsToDocuments($search->indexes, [$result->getDocument()]),
1
);
}
Expand All @@ -105,52 +103,68 @@ public function search(Search $search): Result
}

$index = $search->indexes[\array_key_first($search->indexes)];
$searchIndex = $this->client->index($index->name);
$this->client->getEndpoint()
->setCollection($index->name);


$query = $this->client->createSelect();

$queryText = null;

$query = null;
$filters = [];
foreach ($search->filters as $filter) {
match (true) {
$filter instanceof Condition\IdentifierCondition => $filters[] = $index->getIdentifierField()->name . ' = "' . $filter->identifier . '"', // TODO escape?
$filter instanceof Condition\SearchCondition => $query = $filter->query,
$filter instanceof Condition\EqualCondition => $filters[] = $filter->field . ' = ' . $filter->value, // TODO escape?
$filter instanceof Condition\NotEqualCondition => $filters[] = $filter->field . ' != ' . $filter->value, // TODO escape?
$filter instanceof Condition\GreaterThanCondition => $filters[] = $filter->field . ' > ' . $filter->value, // TODO escape?
$filter instanceof Condition\GreaterThanEqualCondition => $filters[] = $filter->field . ' >= ' . $filter->value, // TODO escape?
$filter instanceof Condition\LessThanCondition => $filters[] = $filter->field . ' < ' . $filter->value, // TODO escape?
$filter instanceof Condition\LessThanEqualCondition => $filters[] = $filter->field . ' <= ' . $filter->value, // TODO escape?
$filter instanceof Condition\SearchCondition => $queryText = $filter->query,
$filter instanceof Condition\IdentifierCondition => $filters[] = $index->getIdentifierField()->name . ':"' . $filter->identifier . '"', // TODO escape?
$filter instanceof Condition\EqualCondition => $filters[] = $filter->field . ':"' . $filter->value . '"', // TODO escape?
$filter instanceof Condition\NotEqualCondition => $filters[] = '-' . $filter->field . ':"' . $filter->value . '"', // TODO escape?
$filter instanceof Condition\GreaterThanCondition => $filters[] = $filter->field . ' >= "' . $filter->value . '"', // TODO escape?
$filter instanceof Condition\GreaterThanEqualCondition => $filters[] = $filter->field . ' > "' . $filter->value . '"', // TODO escape?
$filter instanceof Condition\LessThanCondition => $filters[] = $filter->field . ' <= "' . $filter->value . '"', // TODO escape?
$filter instanceof Condition\LessThanEqualCondition => $filters[] = $filter->field . ' < "' . $filter->value . '"', // TODO escape?
default => throw new \LogicException($filter::class . ' filter not implemented.'),
};
}

$searchParams = [];
if (\count($filters) !== 0) {
$searchParams = ['filter' => \implode(' AND ', $filters)];
if ($queryText !== null) {
$query->setQuery($queryText);
}

foreach ($filters as $key => $filter) {
$query->createFilterQuery('filter_' . $key)->setQuery($filter);
}

if ($search->offset) {
$searchParams['offset'] = $search->offset;
$query->setStart($search->offset);
}

if ($search->limit) {
$searchParams['limit'] = $search->limit;
$query->setRows($search->limit);
}

/*
$searchParams = [];
if (\count($filters) !== 0) {
$searchParams = ['filter' => \implode(' AND ', $filters)];
}
TODO
foreach ($search->sortBys as $field => $direction) {
$searchParams['sort'][] = $field . ':' . $direction;
}
*/

$data = $searchIndex->search($query, $searchParams)->toArray();
$result = $this->client->select($query);

return new Result(
$this->hitsToDocuments($search->indexes, $data['hits']),
$data['totalHits'] ?? $data['estimatedTotalHits'] ?? null,
$this->hitsToDocuments($search->indexes, $result->getDocuments()),
$result->getNumFound()
);
}

/**
* @param Index[] $indexes
* @param iterable<array<string, mixed>> $hits
* @param iterable<\Solarium\QueryType\Select\Result\Document> $hits
*
* @return \Generator<array<string, mixed>>
*/
Expand All @@ -159,6 +173,8 @@ private function hitsToDocuments(array $indexes, iterable $hits): \Generator
$index = $indexes[\array_key_first($indexes)];

foreach ($hits as $hit) {
$hit = $hit->getFields();

unset($hit['_version_']);

if ($index->getIdentifierField()->name !== 'id') {
Expand Down
31 changes: 27 additions & 4 deletions packages/seal/Testing/AbstractConnectionTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ public function testLimitAndOffset(): void
->limit(1);

$loadedDocuments = [...$search->getResult()];
$this->assertCount(1, $loadedDocuments);
$this->assertCount(1, count($loadedDocuments));

$this->assertTrue(
[$documents[0]] === $loadedDocuments
Expand All @@ -259,7 +259,7 @@ public function testLimitAndOffset(): void
->limit(1);

$loadedDocuments = [...$search->getResult()];
$this->assertCount(1, $loadedDocuments);
$this->assertCount(1, count($loadedDocuments));
$this->assertSame(
$isFirstDocumentOnPage1 ? [$documents[1]] : [$documents[0]],
$loadedDocuments
Expand Down Expand Up @@ -341,7 +341,7 @@ public function testMultiEqualCondition(): void
$search->addFilter(new Condition\EqualCondition('tags', 'UX'));

$loadedDocuments = [...$search->getResult()];
$this->assertCount(1, $loadedDocuments);
$this->assertCount(1, count($loadedDocuments));

$this->assertSame(
[$documents[1]],
Expand Down Expand Up @@ -423,7 +423,7 @@ public function testGreaterThanCondition(): void
$search->addFilter(new Condition\GreaterThanCondition('rating', 2.5));

$loadedDocuments = [...$search->getResult()];
$this->assertCount(1, $loadedDocuments);
$this->assertGreaterThan(1, count($loadedDocuments));

foreach ($loadedDocuments as $loadedDocument) {
$this->assertGreaterThan(2.5, $loadedDocument['rating']);
Expand Down Expand Up @@ -458,7 +458,14 @@ public function testGreaterThanEqualCondition(): void
$search->addFilter(new Condition\GreaterThanEqualCondition('rating', 2.5));

$loadedDocuments = [...$search->getResult()];
$this->assertGreaterThan(1, count($loadedDocuments));

foreach ($loadedDocuments as $loadedDocument) {
$this->assertNotNull(
$loadedDocument['rating'] ?? null,
'Expected only documents with rating document "' . $document['uuid'] . '" without rating returned.'
);

$this->assertGreaterThanOrEqual(2.5, $loadedDocument['rating']);
}

Expand Down Expand Up @@ -491,7 +498,14 @@ public function testLessThanCondition(): void
$search->addFilter(new Condition\LessThanCondition('rating', 3.5));

$loadedDocuments = [...$search->getResult()];
$this->assertGreaterThan(1, count($loadedDocuments));

foreach ($loadedDocuments as $loadedDocument) {
$this->assertNotNull(
$loadedDocument['rating'] ?? null,
'Expected only documents with rating document "' . $document['uuid'] . '" without rating returned.'
);

$this->assertLessThan(3.5, $loadedDocument['rating']);
}

Expand Down Expand Up @@ -524,7 +538,14 @@ public function testLessThanEqualCondition(): void
$search->addFilter(new Condition\LessThanEqualCondition('rating', 3.5));

$loadedDocuments = [...$search->getResult()];
$this->assertGreaterThan(1, count($loadedDocuments));

foreach ($loadedDocuments as $loadedDocument) {
$this->assertNotNull(
$loadedDocument['rating'] ?? null,
'Expected only documents with rating document "' . $document['uuid'] . '" without rating returned.'
);

$this->assertLessThanOrEqual(3.5, $loadedDocument['rating']);
}

Expand Down Expand Up @@ -558,6 +579,7 @@ public function testSortByAsc(): void
$search->addSortBy('rating', 'asc');

$loadedDocuments = [...$search->getResult()];
$this->assertGreaterThan(1, count($loadedDocuments));

foreach ($documents as $document) {
self::$taskHelper->tasks[] = self::$connection->delete(
Expand Down Expand Up @@ -596,6 +618,7 @@ public function testSortByDesc(): void
$search->addSortBy('rating', 'desc');

$loadedDocuments = [...$search->getResult()];
$this->assertGreaterThan(1, count($loadedDocuments));

foreach ($documents as $document) {
self::$taskHelper->tasks[] = self::$connection->delete(
Expand Down

0 comments on commit 1ce0539

Please sign in to comment.