Skip to content

Commit d4e3876

Browse files
updated upsert fix, added sum fix
1 parent 1a4151d commit d4e3876

File tree

3 files changed

+83
-5
lines changed

3 files changed

+83
-5
lines changed

src/Database/Adapter/SQL.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3286,7 +3286,18 @@ public function sum(Document $collection, string $attribute, array $queries = []
32863286

32873287
$queries = array_map(fn ($query) => clone $query, $queries);
32883288

3289-
$conditions = $this->getSQLConditions($queries, $binds);
3289+
// Extract vector queries (used for ORDER BY) and keep non-vector for WHERE
3290+
$vectorQueries = [];
3291+
$otherQueries = [];
3292+
foreach ($queries as $query) {
3293+
if (in_array($query->getMethod(), Query::VECTOR_TYPES)) {
3294+
$vectorQueries[] = $query;
3295+
} else {
3296+
$otherQueries[] = $query;
3297+
}
3298+
}
3299+
3300+
$conditions = $this->getSQLConditions($otherQueries, $binds);
32903301
if (!empty($conditions)) {
32913302
$where[] = $conditions;
32923303
}
@@ -3304,11 +3315,22 @@ public function sum(Document $collection, string $attribute, array $queries = []
33043315
? 'WHERE ' . \implode(' AND ', $where)
33053316
: '';
33063317

3318+
// Add vector distance calculations to ORDER BY (similarity-aware LIMIT)
3319+
$vectorOrders = [];
3320+
foreach ($vectorQueries as $query) {
3321+
$vectorOrder = $this->getVectorDistanceOrder($query, $binds, $alias);
3322+
if ($vectorOrder) {
3323+
$vectorOrders[] = $vectorOrder;
3324+
}
3325+
}
3326+
$sqlOrder = !empty($vectorOrders) ? 'ORDER BY ' . implode(', ', $vectorOrders) : '';
3327+
33073328
$sql = "
33083329
SELECT SUM({$this->quote($attribute)}) as sum FROM (
33093330
SELECT {$this->quote($attribute)}
33103331
FROM {$this->getSQLTable($name)} AS {$this->quote($alias)}
33113332
{$sqlWhere}
3333+
{$sqlOrder}
33123334
{$limit}
33133335
) table_count
33143336
";

src/Database/Database.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -603,12 +603,12 @@ function (mixed $value) {
603603
return \json_encode(\array_map(\floatval(...), $value));
604604
},
605605
/**
606-
* @param mixed $value
606+
* @param string|null $value
607607
* @return array|null
608608
*/
609-
function (mixed $value) {
609+
function (?string $value) {
610610
if (is_null($value)) {
611-
return;
611+
return null;
612612
}
613613
if (!is_string($value)) {
614614
return $value;
@@ -6149,7 +6149,6 @@ public function upsertDocumentsWithIncrease(
61496149

61506150
if (!$old->isEmpty()) {
61516151
$old = $this->adapter->castingAfter($collection, $old);
6152-
$old = $this->decode($collection, $old);
61536152
}
61546153

61556154
try {

tests/e2e/Adapter/Scopes/VectorTests.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,6 +2654,63 @@ public function testVectorQueryCount(): void
26542654
$database->deleteCollection('vectorCount');
26552655
}
26562656

2657+
public function testVectorQuerySum(): void
2658+
{
2659+
/** @var Database $database */
2660+
$database = static::getDatabase();
2661+
2662+
if (!$database->getAdapter()->getSupportForVectors()) {
2663+
$this->expectNotToPerformAssertions();
2664+
return;
2665+
}
2666+
2667+
$database->createCollection('vectorSum');
2668+
$database->createAttribute('vectorSum', 'embedding', Database::VAR_VECTOR, 3, true);
2669+
$database->createAttribute('vectorSum', 'value', Database::VAR_INTEGER, 0, true);
2670+
2671+
// Create documents with different values
2672+
$database->createDocument('vectorSum', new Document([
2673+
'$permissions' => [
2674+
Permission::read(Role::any())
2675+
],
2676+
'embedding' => [1.0, 0.0, 0.0],
2677+
'value' => 10
2678+
]));
2679+
2680+
$database->createDocument('vectorSum', new Document([
2681+
'$permissions' => [
2682+
Permission::read(Role::any())
2683+
],
2684+
'embedding' => [0.0, 1.0, 0.0],
2685+
'value' => 20
2686+
]));
2687+
2688+
$database->createDocument('vectorSum', new Document([
2689+
'$permissions' => [
2690+
Permission::read(Role::any())
2691+
],
2692+
'embedding' => [0.5, 0.5, 0.0],
2693+
'value' => 30
2694+
]));
2695+
2696+
// Test sum with vector query - should sum all matching documents
2697+
$sum = $database->sum('vectorSum', 'value', [
2698+
Query::vectorCosine('embedding', [1.0, 0.0, 0.0]),
2699+
]);
2700+
2701+
$this->assertEquals(60, $sum);
2702+
2703+
// Test sum with vector query and filter combined
2704+
$sum = $database->sum('vectorSum', 'value', [
2705+
Query::vectorCosine('embedding', [1.0, 0.0, 0.0]),
2706+
Query::greaterThan('value', 15),
2707+
]);
2708+
2709+
$this->assertEquals(50, $sum);
2710+
2711+
$database->deleteCollection('vectorSum');
2712+
}
2713+
26572714
public function testVetorUpsert(): void
26582715
{
26592716
/** @var Database $database */

0 commit comments

Comments
 (0)