Skip to content

PHPLIB-1859 Add Psalm array shapes for search and vector search index definitions#1899

Open
GromNaN wants to merge 5 commits into
mongodb:v2.xfrom
GromNaN:PHPLIB-1859
Open

PHPLIB-1859 Add Psalm array shapes for search and vector search index definitions#1899
GromNaN wants to merge 5 commits into
mongodb:v2.xfrom
GromNaN:PHPLIB-1859

Conversation

@GromNaN
Copy link
Copy Markdown
Member

@GromNaN GromNaN commented May 20, 2026

Adds typed @psalm-type shapes to Collection for all search and vector search index structures, including storedSource support in VectorSearchIndexDefinitionShape (PHPLIB-1859) and SearchIndexDefinitionShape.

The shapes are adapted from laravel-mongodb, which defines equivalent PHPStan types.

  • Renames OperationTypeOperationShape in BulkWrite for naming consistency
  • Defines shapes: SearchIndexFieldShape, SearchIndexCharFilterShape, SearchIndexTokenFilterShape, SearchIndexAnalyzerShape, SearchIndexStoredSourceShape, SearchIndexSynonymShape, SearchIndexDefinitionShape, VectorSearchIndexFieldShape, VectorSearchIndexDefinitionShape, SearchIndexShape
  • Updates @param on createSearchIndex, createSearchIndexes, updateSearchIndex
  • SearchIndexInput imports SearchIndexShape from Collection via @psalm-import-type
  • Adds tests/Type/SearchIndexShapes.php and tests/Type/BulkWriteShapes.php with Psalm type tests based on documentation examples
  • Adds tests/Type/ to psalm.xml.dist

… definitions

Adds typed `@psalm-type` shapes to `Collection` for all search index structures
(`SearchIndexDefinitionShape`, `VectorSearchIndexDefinitionShape`, and their
subtypes), including `storedSource` support in both. Renames `OperationType`
to `OperationShape` for consistency. Adds Psalm type tests in `tests/Type/`.
Copilot AI review requested due to automatic review settings May 20, 2026 16:56
@GromNaN GromNaN requested a review from a team as a code owner May 20, 2026 16:56
@GromNaN GromNaN requested a review from paulinevos May 20, 2026 16:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Psalm array-shape aliases for Atlas Search and Atlas Vector Search index definitions and wires those shapes into Collection APIs and the internal SearchIndexInput model, with a new Psalm-only type test file to validate documentation examples.

Changes:

  • Introduces @psalm-type aliases in src/Collection.php for search/vector index definitions (including storedSource) and uses them in createSearchIndex()/createSearchIndexes()/updateSearchIndex() phpdocs.
  • Renames the BulkWrite operation psalm alias from OperationType to OperationShape and updates dependent annotations.
  • Adds tests/Type/SearchIndexShapes.php and includes tests/Type in Psalm config so these shape examples are type-checked.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Type/SearchIndexShapes.php Adds Psalm-only type checks using documentation-style examples for search/vector index definitions.
src/Operation/BulkWrite.php Renames the psalm alias for bulk write operations to OperationShape and updates related annotations.
src/Model/SearchIndexInput.php Switches the input model to reference the imported SearchIndexShape alias.
src/Collection.php Defines search/vector index shape aliases and updates related method annotations/usages.
psalm.xml.dist Adds tests/Type/ to Psalm’s analyzed project files.
Comments suppressed due to low confidence (1)

src/Model/SearchIndexInput.php:52

  • The constructor validates $index['definition'] with is_document, which allows both arrays and objects, but the new @param SearchIndexShape depends on SearchIndexShape currently restricting definition to array shapes only. This will cause Psalm to reject valid object definitions. Align the imported shape (or override with a @psalm-param here) so definition can be an object as well.
 * @psalm-import-type SearchIndexShape from Collection
 */
final class SearchIndexInput implements Serializable
{
    /**
     * @param SearchIndexShape $index Search index specification
     * @throws InvalidArgumentException
     */
    public function __construct(private array $index)
    {
        if (! isset($index['definition'])) {
            throw new InvalidArgumentException('Required "definition" document is missing from search index specification');
        }

        if (! is_document($index['definition'])) {
            throw InvalidArgumentException::expectedDocumentType('"definition" option', $index['definition']);

Comment thread src/Collection.php Outdated
Comment thread src/Collection.php Outdated
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.72%. Comparing base (4ae7e29) to head (cf941cd).
⚠️ Report is 3 commits behind head on v2.x.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               v2.x    #1899      +/-   ##
============================================
- Coverage     87.74%   87.72%   -0.02%     
- Complexity     3319     3328       +9     
============================================
  Files           451      454       +3     
  Lines          6632     6657      +25     
============================================
+ Hits           5819     5840      +21     
- Misses          813      817       +4     
Flag Coverage Δ
6.0-replica_set 86.57% <100.00%> (-0.01%) ⬇️
6.0-server 82.61% <100.00%> (+<0.01%) ⬆️
6.0-sharded_cluster 86.36% <100.00%> (-0.01%) ⬇️
8.0-replica_set 87.59% <100.00%> (-0.02%) ⬇️
8.0-server 83.35% <100.00%> (+<0.01%) ⬆️
8.0-sharded_cluster ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@GromNaN GromNaN requested a review from alcaeus May 20, 2026 17:16
…remove redundant array from updateSearchIndex param
Copilot AI review requested due to automatic review settings May 20, 2026 17:17
Comment thread src/Collection.php
/** @phpstan-import-type OperationType from BulkWrite */
/**
* @psalm-import-type OperationShape from BulkWrite
* @psalm-type SearchIndexFieldShape = array{
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this shapes in the Collection class because that's where they are used. And the SearchIndexInput class is internal, so it can't expose a psalm type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Is this a limitation from psalm/phpstan?

*
* @psalm-type Document = object|array
* @psalm-type OperationType = array{deleteMany: array{0: Document, 1?: array}}|array{deleteOne: array{0: Document, 1?: array}}|array{insertOne: array{0: Document}}|array{replaceOne: array{0: Document, 1: Document, 2?: array}}|array{updateMany: array{0: Document, 1: Document, 2?: array}}|array{updateOne: array{0: Document, 1: Document, 2?: array}}
* @psalm-type OperationShape = array{deleteMany: array{0: Document, 1?: array}}|array{deleteOne: array{0: Document, 1?: array}}|array{insertOne: array{0: Document}}|array{replaceOne: array{0: Document, 1: Document, 2?: array}}|array{updateMany: array{0: Document, 1: Document, 2?: array}}|array{updateOne: array{0: Document, 1: Document, 2?: array}}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shape can be improved using the query operators once we generate array shapes for the agg builder.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread src/Collection.php Outdated
Comment thread tests/Type/SearchIndexShapes.php
Copilot AI review requested due to automatic review settings May 20, 2026 18:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment thread src/Collection.php
Comment thread src/Collection.php
Comment thread tests/Type/BulkWriteShapes.php Outdated
Copy link
Copy Markdown
Member

@alcaeus alcaeus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; good to merge once CI is alive again.

Comment on lines +25 to +26
* This file is not executed by PHPUnit; it is only checked by Psalm to verify
* that the OperationShape defined in BulkWrite is accepted by Collection::bulkWrite.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting strategy, I like it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants