Skip to content

Commit

Permalink
Fixed filtering on negative coordinates was not supported (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
Toflar authored Apr 22, 2024
1 parent cda7035 commit 68889a2
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 6 deletions.
5 changes: 5 additions & 0 deletions src/Internal/Filter/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Lexer extends AbstractLexer

public const T_LOWER_THAN = 13;

public const T_MINUS = 20;

public const T_NEGATE = 16;

public const T_NONE = 1;
Expand Down Expand Up @@ -106,6 +108,9 @@ protected function getType(mixed &$value): int
case $value === 'true':
return self::T_TRUE;

case $value === '-':
return self::T_MINUS;

case $value === '_geoRadius':
return self::T_GEO_RADIUS;

Expand Down
19 changes: 15 additions & 4 deletions src/Internal/Filter/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ private function addNode(Node $node): self
return $this;
}

private function assertAndExtractFloat(?Token $token, bool $allowNegative = false): float
{
$multipler = 1;
if ($allowNegative && $token !== null && $token->type === Lexer::T_MINUS) {
$multipler = -1;
$this->lexer->moveNext();
$token = $this->lexer->token;
}

$this->assertFloat($token);
return (float) $this->lexer->token?->value * $multipler;
}

private function assertClosingParenthesis(?Token $token): void
{
$this->assertTokenTypes($token, [Lexer::T_CLOSE_PARENTHESIS], "')'");
Expand Down Expand Up @@ -232,14 +245,12 @@ private function handleGeoRadius(Engine $engine): void
$this->validateFilterableAttribute($engine, $attributeName);

$this->lexer->moveNext();
$this->assertFloat($this->lexer->lookahead);
$this->lexer->moveNext();
$lat = (float) $this->lexer->token?->value;
$lat = $this->assertAndExtractFloat($this->lexer->token, true);
$this->assertComma($this->lexer->lookahead);
$this->lexer->moveNext();
$this->assertFloat($this->lexer->lookahead);
$this->lexer->moveNext();
$lng = (float) $this->lexer->token?->value;
$lng = $this->assertAndExtractFloat($this->lexer->token, true);
$this->assertComma($this->lexer->lookahead);
$this->lexer->moveNext();
$this->assertFloat($this->lexer->lookahead);
Expand Down
13 changes: 12 additions & 1 deletion tests/Functional/IndexData/restaurants.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,16 @@
"lat": 45.4632046,
"lng": 9.1719421
}
},
{
"id": 4,
"name": "Revire Brasas Bravas",
"address": "Av. Corrientes 1124, C1043 Cdad. Autónoma de Buenos Aires, Argentina",
"type": "steak",
"rating": 10,
"location": {
"lat": -34.6002321,
"lng": -58.3823691
}
}
]
]
35 changes: 34 additions & 1 deletion tests/Functional/SearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,30 @@ public function testGeoSearch(): void
'totalHits' => 2,
]);

$searchParameters = SearchParameters::create()
->withAttributesToRetrieve(['id', 'name', 'location'])
->withFilter('_geoRadius(location, -34.5567580, -58.4153774, 10000)') // search with negative coordinates
->withSort(['_geoPoint(location, -34.5567580, -58.4153774):asc']) // sort with negative coordinates
;

$this->searchAndAssertResults($loupe, $searchParameters, [
'hits' => [
[
'id' => 4,
'name' => 'Revire Brasas Bravas',
'location' => [
'lat' => -34.6002321,
'lng' => -58.3823691,
],
],
],
'query' => '',
'hitsPerPage' => 20,
'page' => 1,
'totalPages' => 1,
'totalHits' => 1,
]);

$searchParameters = SearchParameters::create()
->withAttributesToRetrieve(['id', 'name', 'location', '_geoDistance(location)'])
->withSort(['_geoPoint(location, 48.8561446,2.2978204):asc'])
Expand Down Expand Up @@ -1032,12 +1056,21 @@ public function testGeoSearch(): void
],
'_geoDistance(location)' => 642336,
],
[
'id' => 4,
'name' => 'Revire Brasas Bravas',
'location' => [
'lat' => -34.6002321,
'lng' => -58.3823691,
],
'_geoDistance(location)' => 11046932,
],
],
'query' => '',
'hitsPerPage' => 20,
'page' => 1,
'totalPages' => 1,
'totalHits' => 3,
'totalHits' => 4,
]);
}

Expand Down
12 changes: 12 additions & 0 deletions tests/Unit/Internal/Filter/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ public static function filterProvider(): \Generator
],
];

yield 'Basic geo filter with negative coordinates' => [
'_geoRadius(location, -34.5567580, -58.4153774, 2000)',
[
[
'attribute' => 'location',
'lat' => -34.5567580,
'lng' => -58.4153774,
'distance' => 2000.0,
],
],
];

yield 'Basic IN filter' => [
"genres IN ('Drama', 'Action', 'Documentary')",
[
Expand Down

0 comments on commit 68889a2

Please sign in to comment.