-
Notifications
You must be signed in to change notification settings - Fork 0
feat: cross-collection Qdrant search #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4fcf21f
8c4e36b
909baea
a1a0f55
26f77eb
b3e88e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -977,4 +977,32 @@ public function getCollectionName(string $project): string | |||||
| { | ||||||
| return 'knowledge_'.str_replace(['/', '\\', ' '], '_', $project); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Search any Qdrant collection by name — no knowledge_ prefix, no metadata mapping. | ||||||
| * | ||||||
| * @return Collection<int, array{id: string|int, score: float, payload: array<string, mixed>}> | ||||||
| */ | ||||||
| public function searchRawCollection(string $collection, string $query, int $limit = 10): Collection | ||||||
| { | ||||||
| $queryVector = $this->getCachedEmbedding($query); | ||||||
|
|
||||||
| if ($queryVector === []) { | ||||||
| return collect(); | ||||||
| } | ||||||
|
|
||||||
| $response = $this->connector->send( | ||||||
| new SearchPoints($collection, $queryVector, $limit, 0.0) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Setting score_threshold to 0.0 in Qdrant's /collections/{name}/points/search endpoint effectively disables the score filtering, returning up to the specified limit of the top closest points regardless of their similarity score (even scores as low as 0 or negative, depending on the distance metric). In contrast, a positive threshold like 0.7 filters out results below that score, potentially returning fewer than limit points if insufficient matches exceed the threshold. This behavior holds for similarity metrics where higher scores indicate better matches (e.g., Cosine: 0-1, Dot: -∞ to ∞), ensuring all returned results meet the minimum quality while 0.0 prioritizes quantity up to the limit. Citations:
🏁 Script executed: # First, let's examine the QdrantService.php file around line 995
sed -n '985,1005p' app/Services/QdrantService.phpRepository: conduit-ui/knowledge Length of output: 729 🏁 Script executed: # Search for scoreThreshold property definition in the file
rg 'scoreThreshold' app/Services/QdrantService.php -nRepository: conduit-ui/knowledge Length of output: 163 🏁 Script executed: # Check the constructor and property initialization
sed -n '1,100p' app/Services/QdrantService.php | grep -n 'class\|function __construct\|scoreThreshold\|private\|protected\|public'Repository: conduit-ui/knowledge Length of output: 905 🏁 Script executed: # Check context around line 445 where scoreThreshold is used
sed -n '440,450p' app/Services/QdrantService.phpRepository: conduit-ui/knowledge Length of output: 379 🏁 Script executed: # Search for all SearchPoints instantiations to see the pattern
rg 'new SearchPoints' app/Services/QdrantService.php -n -A 1 -B 1Repository: conduit-ui/knowledge Length of output: 481 Use configured relevance threshold instead of hard-coding Line 995 hard-codes Suggested fix- $response = $this->connector->send(
- new SearchPoints($collection, $queryVector, $limit, 0.0)
- );
+ $response = $this->connector->send(
+ new SearchPoints($collection, $queryVector, $limit, $this->scoreThreshold)
+ );📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| ); | ||||||
|
|
||||||
| if (! $response->successful()) { | ||||||
| return collect(); | ||||||
| } | ||||||
|
|
||||||
| return collect($response->json('result') ?? [])->map(fn (array $r): array => [ | ||||||
| 'id' => $r['id'], | ||||||
| 'score' => $r['score'] ?? 0.0, | ||||||
| 'payload' => $r['payload'] ?? [], | ||||||
| ]); | ||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
In PHP 8.x, what happens when an array is interpolated into a double-quoted string (e.g., "{$value}")?💡 Result:
In PHP 8.x, when an array $value is interpolated into a double-quoted string using "{$value}", the array is converted to the string "Array" and inserted into the string. This behavior occurs because PHP automatically converts arrays to the string "Array" in string contexts, such as interpolation in double-quoted strings. For example: $value = ['a' => 'hello', 'b' => 'world']; echo "{$value}"; // Outputs: Array To interpolate a specific array element, use array access syntax within the curly braces, such as "{$value['key']}", which evaluates the expression and inserts the element's string representation. Simple syntax like "$value[key]" works only for unquoted keys in basic interpolation, but complex access requires curly braces. This has been consistent across PHP versions, including 8.x, with no changes specific to array interpolation in double-quoted strings (PHP 8 introduced dereferencing for interpolated strings like "foo$bar"[0], but not for whole arrays).
Citations:
🏁 Script executed:
Repository: conduit-ui/knowledge
Length of output: 912
🏁 Script executed:
rg -n '\$payload' app/Commands/KnowledgeSearchCommand.php -B 2 -A 2Repository: conduit-ui/knowledge
Length of output: 564
🏁 Script executed:
Repository: conduit-ui/knowledge
Length of output: 1173
🏁 Script executed:
Repository: conduit-ui/knowledge
Length of output: 366
🏁 Script executed:
rg -n 'strict_types' app/ -iRepository: conduit-ui/knowledge
Length of output: 6235
🏁 Script executed:
Repository: conduit-ui/knowledge
Length of output: 1247
🏁 Script executed:
Repository: conduit-ui/knowledge
Length of output: 2106
🏁 Script executed:
rg -n 'payload.*=>' app/Services/QdrantService.php -B 3 -A 3Repository: conduit-ui/knowledge
Length of output: 636
🏁 Script executed:
rg -n '"payload"' app/Services/QdrantService.php -B 2 -A 2Repository: conduit-ui/knowledge
Length of output: 46
🏁 Script executed:
Repository: conduit-ui/knowledge
Length of output: 2246
🏁 Script executed:
sed -n '150,210p' app/Services/QdrantService.phpRepository: conduit-ui/knowledge
Length of output: 2840
🏁 Script executed:
rg -n "description" app/Services/QdrantService.phpRepository: conduit-ui/knowledge
Length of output: 46
🏁 Script executed:
rg -n "description" app/Commands/KnowledgeSearchCommand.php -B 2 -A 2Repository: conduit-ui/knowledge
Length of output: 764
Safely serialize non-scalar payload values before displaying.
Array and object fields in
$payload(liketagsorevidence) will display as the literal string "Array" when directly interpolated, producing unreadable output. Line 181's map closure accepts any non-null, non-empty value and interpolates it directly without type checking.Additionally, line 175's
json_encode($payload)fallback should include JSON flags to handle edge cases like unescaped unicode and invalid UTF-8 sequences.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents