Skip to content

Commit 5e4e4bd

Browse files
added spatial attribute support for the sum, count methods
1 parent 07e7de7 commit 5e4e4bd

File tree

6 files changed

+115
-21
lines changed

6 files changed

+115
-21
lines changed

src/Database/Adapter.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,25 +783,25 @@ abstract public function find(Document $collection, array $queries = [], ?int $l
783783
/**
784784
* Sum an attribute
785785
*
786-
* @param string $collection
786+
* @param Document $collection
787787
* @param string $attribute
788788
* @param array<Query> $queries
789789
* @param int|null $max
790790
*
791791
* @return int|float
792792
*/
793-
abstract public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): float|int;
793+
abstract public function sum(Document $collection, string $attribute, array $queries = [], ?int $max = null): float|int;
794794

795795
/**
796796
* Count Documents
797797
*
798-
* @param string $collection
798+
* @param Document $collection
799799
* @param array<Query> $queries
800800
* @param int|null $max
801801
*
802802
* @return int
803803
*/
804-
abstract public function count(string $collection, array $queries = [], ?int $max = null): int;
804+
abstract public function count(Document $collection, array $queries = [], ?int $max = null): int;
805805

806806
/**
807807
* Get Collection Size of the raw data

src/Database/Adapter/MariaDB.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,15 +1548,17 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25
15481548
/**
15491549
* Count Documents
15501550
*
1551-
* @param string $collection
1551+
* @param Document $collection
15521552
* @param array<Query> $queries
15531553
* @param int|null $max
15541554
* @return int
15551555
* @throws Exception
15561556
* @throws PDOException
15571557
*/
1558-
public function count(string $collection, array $queries = [], ?int $max = null): int
1558+
public function count(Document $collection, array $queries = [], ?int $max = null): int
15591559
{
1560+
$attributes = $collection->getAttribute("attributes", []);
1561+
$collection = $collection->getId();
15601562
$name = $this->filter($collection);
15611563
$roles = Authorization::getRoles();
15621564
$binds = [];
@@ -1571,7 +1573,7 @@ public function count(string $collection, array $queries = [], ?int $max = null)
15711573

15721574
$queries = array_map(fn ($query) => clone $query, $queries);
15731575

1574-
$conditions = $this->getSQLConditions($queries, $binds);
1576+
$conditions = $this->getSQLConditions($queries, $binds, attributes:$attributes);
15751577
if (!empty($conditions)) {
15761578
$where[] = $conditions;
15771579
}
@@ -1620,16 +1622,18 @@ public function count(string $collection, array $queries = [], ?int $max = null)
16201622
/**
16211623
* Sum an Attribute
16221624
*
1623-
* @param string $collection
1625+
* @param Document $collection
16241626
* @param string $attribute
16251627
* @param array<Query> $queries
16261628
* @param int|null $max
16271629
* @return int|float
16281630
* @throws Exception
16291631
* @throws PDOException
16301632
*/
1631-
public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): int|float
1633+
public function sum(Document $collection, string $attribute, array $queries = [], ?int $max = null): int|float
16321634
{
1635+
$collectionAttributes = $collection->getAttribute("attributes", []);
1636+
$collection = $collection->getId();
16331637
$name = $this->filter($collection);
16341638
$roles = Authorization::getRoles();
16351639
$where = [];
@@ -1644,7 +1648,7 @@ public function sum(string $collection, string $attribute, array $queries = [],
16441648

16451649
$queries = array_map(fn ($query) => clone $query, $queries);
16461650

1647-
$conditions = $this->getSQLConditions($queries, $binds);
1651+
$conditions = $this->getSQLConditions($queries, $binds, attributes:$collectionAttributes);
16481652
if (!empty($conditions)) {
16491653
$where[] = $conditions;
16501654
}

src/Database/Adapter/Pool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,12 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25
265265
return $this->delegate(__FUNCTION__, \func_get_args());
266266
}
267267

268-
public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): float|int
268+
public function sum(Document $collection, string $attribute, array $queries = [], ?int $max = null): float|int
269269
{
270270
return $this->delegate(__FUNCTION__, \func_get_args());
271271
}
272272

273-
public function count(string $collection, array $queries = [], ?int $max = null): int
273+
public function count(Document $collection, array $queries = [], ?int $max = null): int
274274
{
275275
return $this->delegate(__FUNCTION__, \func_get_args());
276276
}

src/Database/Adapter/Postgres.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,16 +1634,17 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25
16341634

16351635
/**
16361636
* Count Documents
1637-
*
1638-
* @param string $collection
1637+
* @param Document $collection
16391638
* @param array<Query> $queries
16401639
* @param int|null $max
16411640
* @return int
16421641
* @throws Exception
16431642
* @throws PDOException
16441643
*/
1645-
public function count(string $collection, array $queries = [], ?int $max = null): int
1644+
public function count(Document $collection, array $queries = [], ?int $max = null): int
16461645
{
1646+
$collectionAttributes = $collection->getAttribute("attributes", []);
1647+
$collection = $collection->getId();
16471648
$name = $this->filter($collection);
16481649
$roles = Authorization::getRoles();
16491650
$binds = [];
@@ -1658,7 +1659,7 @@ public function count(string $collection, array $queries = [], ?int $max = null)
16581659

16591660
$queries = array_map(fn ($query) => clone $query, $queries);
16601661

1661-
$conditions = $this->getSQLConditions($queries, $binds);
1662+
$conditions = $this->getSQLConditions($queries, $binds, attributes:$collectionAttributes);
16621663
if (!empty($conditions)) {
16631664
$where[] = $conditions;
16641665
}
@@ -1708,16 +1709,18 @@ public function count(string $collection, array $queries = [], ?int $max = null)
17081709
/**
17091710
* Sum an Attribute
17101711
*
1711-
* @param string $collection
1712+
* @param Document $collection
17121713
* @param string $attribute
17131714
* @param array<Query> $queries
17141715
* @param int|null $max
17151716
* @return int|float
17161717
* @throws Exception
17171718
* @throws PDOException
17181719
*/
1719-
public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): int|float
1720+
public function sum(Document $collection, string $attribute, array $queries = [], ?int $max = null): int|float
17201721
{
1722+
$collectionAttributes = $collection->getAttribute("attributes", []);
1723+
$collection = $collection->getId();
17211724
$name = $this->filter($collection);
17221725
$roles = Authorization::getRoles();
17231726
$where = [];
@@ -1732,7 +1735,7 @@ public function sum(string $collection, string $attribute, array $queries = [],
17321735

17331736
$queries = array_map(fn ($query) => clone $query, $queries);
17341737

1735-
$conditions = $this->getSQLConditions($queries, $binds);
1738+
$conditions = $this->getSQLConditions($queries, $binds, attributes:$collectionAttributes);
17361739
if (!empty($conditions)) {
17371740
$where[] = $conditions;
17381741
}

src/Database/Database.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6370,7 +6370,7 @@ public function count(string $collection, array $queries = [], ?int $max = null)
63706370
$queries = Query::groupByType($queries)['filters'];
63716371
$queries = $this->convertQueries($collection, $queries);
63726372

6373-
$getCount = fn () => $this->adapter->count($collection->getId(), $queries, $max);
6373+
$getCount = fn () => $this->adapter->count($collection, $queries, $max);
63746374
$count = $skipAuth ?? false ? Authorization::skip($getCount) : $getCount();
63756375

63766376
$this->trigger(self::EVENT_DOCUMENT_COUNT, $count);
@@ -6415,7 +6415,7 @@ public function sum(string $collection, string $attribute, array $queries = [],
64156415

64166416
$queries = $this->convertQueries($collection, $queries);
64176417

6418-
$sum = $this->adapter->sum($collection->getId(), $attribute, $queries, $max);
6418+
$sum = $this->adapter->sum($collection, $attribute, $queries, $max);
64196419

64206420
$this->trigger(self::EVENT_DOCUMENT_SUM, $sum);
64216421

tests/e2e/Adapter/Scopes/SpatialTests.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,4 +1645,91 @@ public function testSpatialBulkOperation(): void
16451645
// Cleanup
16461646
$database->deleteCollection($collectionName);
16471647
}
1648+
1649+
public function testSptialAggregation(): void
1650+
{
1651+
/** @var Database $database */
1652+
$database = static::getDatabase();
1653+
if (!$database->getAdapter()->getSupportForSpatialAttributes()) {
1654+
$this->markTestSkipped('Adapter does not support spatial attributes');
1655+
}
1656+
$collectionName = 'spatial_agg_';
1657+
try {
1658+
// Create collection with spatial and numeric attributes
1659+
$database->createCollection($collectionName);
1660+
$database->createAttribute($collectionName, 'name', Database::VAR_STRING, 255, true);
1661+
$database->createAttribute($collectionName, 'loc', Database::VAR_POINT, 0, true);
1662+
$database->createAttribute($collectionName, 'area', Database::VAR_POLYGON, 0, true);
1663+
$database->createAttribute($collectionName, 'score', Database::VAR_INTEGER, 0, true);
1664+
1665+
// Spatial indexes
1666+
$database->createIndex($collectionName, 'idx_loc', Database::INDEX_SPATIAL, ['loc']);
1667+
$database->createIndex($collectionName, 'idx_area', Database::INDEX_SPATIAL, ['area']);
1668+
1669+
// Seed documents
1670+
$a = $database->createDocument($collectionName, new Document([
1671+
'$id' => 'a',
1672+
'name' => 'A',
1673+
'loc' => [10.0, 10.0],
1674+
'area' => [[[9.0, 9.0], [9.0, 11.0], [11.0, 11.0], [11.0, 9.0], [9.0, 9.0]]],
1675+
'score' => 10,
1676+
'$permissions' => [Permission::read(Role::any()), Permission::update(Role::any())]
1677+
]));
1678+
$b = $database->createDocument($collectionName, new Document([
1679+
'$id' => 'b',
1680+
'name' => 'B',
1681+
'loc' => [10.05, 10.05],
1682+
'area' => [[[9.5, 9.5], [9.5, 10.6], [10.6, 10.6], [10.6, 9.5], [9.5, 9.5]]],
1683+
'score' => 20,
1684+
'$permissions' => [Permission::read(Role::any()), Permission::update(Role::any())]
1685+
]));
1686+
$c = $database->createDocument($collectionName, new Document([
1687+
'$id' => 'c',
1688+
'name' => 'C',
1689+
'loc' => [50.0, 50.0],
1690+
'area' => [[[49.0, 49.0], [49.0, 51.0], [51.0, 51.0], [51.0, 49.0], [49.0, 49.0]]],
1691+
'score' => 30,
1692+
'$permissions' => [Permission::read(Role::any()), Permission::update(Role::any())]
1693+
]));
1694+
1695+
$this->assertInstanceOf(Document::class, $a);
1696+
$this->assertInstanceOf(Document::class, $b);
1697+
$this->assertInstanceOf(Document::class, $c);
1698+
1699+
// COUNT with spatial distance filter
1700+
$queries = [
1701+
Query::distanceLessThan('loc', [[[10.0, 10.0], 0.1]])
1702+
];
1703+
$this->assertEquals(2, $database->count($collectionName, $queries));
1704+
$this->assertCount(2, $database->find($collectionName, $queries));
1705+
1706+
// SUM with spatial distance filter
1707+
$sumNear = $database->sum($collectionName, 'score', $queries);
1708+
$this->assertEquals(10 + 20, $sumNear);
1709+
1710+
// COUNT and SUM with distanceGreaterThan (should only include far point "c")
1711+
$queriesFar = [
1712+
Query::distanceGreaterThan('loc', [[[10.0, 10.0], 10.0]])
1713+
];
1714+
$this->assertEquals(1, $database->count($collectionName, $queriesFar));
1715+
$this->assertEquals(30, $database->sum($collectionName, 'score', $queriesFar));
1716+
1717+
// COUNT and SUM with polygon contains filter (adapter-dependent boundary inclusivity)
1718+
if ($database->getAdapter()->getSupportForBoundaryInclusiveContains()) {
1719+
$queriesContain = [
1720+
Query::contains('area', [[10.0, 10.0]])
1721+
];
1722+
$this->assertEquals(2, $database->count($collectionName, $queriesContain));
1723+
$this->assertEquals(30, $database->sum($collectionName, 'score', $queriesContain));
1724+
1725+
$queriesNotContain = [
1726+
Query::notContains('area', [[10.0, 10.0]])
1727+
];
1728+
$this->assertEquals(1, $database->count($collectionName, $queriesNotContain));
1729+
$this->assertEquals(30, $database->sum($collectionName, 'score', $queriesNotContain));
1730+
}
1731+
} finally {
1732+
$database->deleteCollection($collectionName);
1733+
}
1734+
}
16481735
}

0 commit comments

Comments
 (0)