@@ -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