diff --git a/generator/mql-specifications b/generator/mql-specifications index 5b4e8630d..3b8ea5297 160000 --- a/generator/mql-specifications +++ b/generator/mql-specifications @@ -1 +1 @@ -Subproject commit 5b4e8630d5e8a794978b9f4004840f104377a7a9 +Subproject commit 3b8ea5297f3c85e9fbcea81787f8f0cd16053345 diff --git a/src/Builder/Stage/FactoryTrait.php b/src/Builder/Stage/FactoryTrait.php index 6f284d183..49dc76049 100644 --- a/src/Builder/Stage/FactoryTrait.php +++ b/src/Builder/Stage/FactoryTrait.php @@ -838,8 +838,8 @@ public static function unwind( * @param string $index Name of the Atlas Vector Search index to use. * @param int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. * @param string $path Indexed vector type field to search. - * @param BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represent the query vector. The number type - * must match the indexed field value type. + * @param Optional|BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represents the query vector. The number type + * must match the indexed field value type. Required if `query` is not specified. * @param Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. * @param Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. * @param Optional|int $numCandidates This field is required if exact is false or omitted. @@ -847,19 +847,32 @@ public static function unwind( * @param Optional|bool $returnStoredSource If true, the search returns only the stored source fields configured on the index directly from the index and skips a full document lookup. If omitted, the default value is false. * @param Optional|Document|Serializable|array|stdClass $nestedOptions Configure how MongoDB Vector Search scores documents that contain nested arrays. * @param Optional|QueryInterface|array $parentFilter Any match query that compares an indexed top-level field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. Only valid if `nestedRoot` is specified in the index definition. + * @param Optional|string $query Natural language text query for automated embedding. MongoDB automatically + * generates a vector embedding for this text at query time using the embedding model + * configured in the index, or the `model` argument if specified. + * Required if `queryVector` is not specified. + * + * New in MongoDB 8.2 + * @param Optional|string $model The embedding model used to generate the query vector from the query text. If omitted, + * the model configured in the index definition is used. Must be compatible with the model + * used at index time. Only valid when `query` is specified. + * + * New in MongoDB 8.2 */ public static function vectorSearch( string $index, int $limit, string $path, - Binary|PackedArray|BSONArray|array|string $queryVector, + Optional|Binary|PackedArray|BSONArray|array|string $queryVector = Optional::Undefined, Optional|bool $exact = Optional::Undefined, Optional|QueryInterface|array $filter = Optional::Undefined, Optional|int $numCandidates = Optional::Undefined, Optional|bool $returnStoredSource = Optional::Undefined, Optional|Document|Serializable|stdClass|array $nestedOptions = Optional::Undefined, Optional|QueryInterface|array $parentFilter = Optional::Undefined, + Optional|string $query = Optional::Undefined, + Optional|string $model = Optional::Undefined, ): VectorSearchStage { - return new VectorSearchStage($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates, $returnStoredSource, $nestedOptions, $parentFilter); + return new VectorSearchStage($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates, $returnStoredSource, $nestedOptions, $parentFilter, $query, $model); } } diff --git a/src/Builder/Stage/FluentFactoryTrait.php b/src/Builder/Stage/FluentFactoryTrait.php index 2176fff50..6bbc76f7d 100644 --- a/src/Builder/Stage/FluentFactoryTrait.php +++ b/src/Builder/Stage/FluentFactoryTrait.php @@ -937,8 +937,8 @@ public function unwind( * @param string $index Name of the Atlas Vector Search index to use. * @param int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. * @param string $path Indexed vector type field to search. - * @param BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represent the query vector. The number type - * must match the indexed field value type. + * @param Optional|BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represents the query vector. The number type + * must match the indexed field value type. Required if `query` is not specified. * @param Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. * @param Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. * @param Optional|int $numCandidates This field is required if exact is false or omitted. @@ -946,20 +946,33 @@ public function unwind( * @param Optional|bool $returnStoredSource If true, the search returns only the stored source fields configured on the index directly from the index and skips a full document lookup. If omitted, the default value is false. * @param Optional|Document|Serializable|array|stdClass $nestedOptions Configure how MongoDB Vector Search scores documents that contain nested arrays. * @param Optional|QueryInterface|array $parentFilter Any match query that compares an indexed top-level field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. Only valid if `nestedRoot` is specified in the index definition. + * @param Optional|string $query Natural language text query for automated embedding. MongoDB automatically + * generates a vector embedding for this text at query time using the embedding model + * configured in the index, or the `model` argument if specified. + * Required if `queryVector` is not specified. + * + * New in MongoDB 8.2 + * @param Optional|string $model The embedding model used to generate the query vector from the query text. If omitted, + * the model configured in the index definition is used. Must be compatible with the model + * used at index time. Only valid when `query` is specified. + * + * New in MongoDB 8.2 */ public function vectorSearch( string $index, int $limit, string $path, - Binary|PackedArray|BSONArray|array|string $queryVector, + Optional|Binary|PackedArray|BSONArray|array|string $queryVector = Optional::Undefined, Optional|bool $exact = Optional::Undefined, Optional|QueryInterface|array $filter = Optional::Undefined, Optional|int $numCandidates = Optional::Undefined, Optional|bool $returnStoredSource = Optional::Undefined, Optional|Document|Serializable|stdClass|array $nestedOptions = Optional::Undefined, Optional|QueryInterface|array $parentFilter = Optional::Undefined, + Optional|string $query = Optional::Undefined, + Optional|string $model = Optional::Undefined, ): static { - $this->pipeline[] = Stage::vectorSearch($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates, $returnStoredSource, $nestedOptions, $parentFilter); + $this->pipeline[] = Stage::vectorSearch($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates, $returnStoredSource, $nestedOptions, $parentFilter, $query, $model); return $this; } diff --git a/src/Builder/Stage/VectorSearchStage.php b/src/Builder/Stage/VectorSearchStage.php index cad030d63..504cf7dc6 100644 --- a/src/Builder/Stage/VectorSearchStage.php +++ b/src/Builder/Stage/VectorSearchStage.php @@ -49,6 +49,8 @@ final class VectorSearchStage implements InputStageInterface, OperatorInterface 'returnStoredSource' => 'returnStoredSource', 'nestedOptions' => 'nestedOptions', 'parentFilter' => 'parentFilter', + 'query' => 'query', + 'model' => 'model', ]; /** @var string $index Name of the Atlas Vector Search index to use. */ @@ -61,10 +63,10 @@ final class VectorSearchStage implements InputStageInterface, OperatorInterface public readonly string $path; /** - * @var BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represent the query vector. The number type - * must match the indexed field value type. + * @var Optional|BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represents the query vector. The number type + * must match the indexed field value type. Required if `query` is not specified. */ - public readonly Binary|PackedArray|BSONArray|array|string $queryVector; + public readonly Optional|Binary|PackedArray|BSONArray|array|string $queryVector; /** @var Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. */ public readonly Optional|bool $exact; @@ -87,12 +89,31 @@ final class VectorSearchStage implements InputStageInterface, OperatorInterface /** @var Optional|QueryInterface|array $parentFilter Any match query that compares an indexed top-level field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. Only valid if `nestedRoot` is specified in the index definition. */ public readonly Optional|QueryInterface|array $parentFilter; + /** + * @var Optional|string $query Natural language text query for automated embedding. MongoDB automatically + * generates a vector embedding for this text at query time using the embedding model + * configured in the index, or the `model` argument if specified. + * Required if `queryVector` is not specified. + * + * New in MongoDB 8.2 + */ + public readonly Optional|string $query; + + /** + * @var Optional|string $model The embedding model used to generate the query vector from the query text. If omitted, + * the model configured in the index definition is used. Must be compatible with the model + * used at index time. Only valid when `query` is specified. + * + * New in MongoDB 8.2 + */ + public readonly Optional|string $model; + /** * @param string $index Name of the Atlas Vector Search index to use. * @param int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. * @param string $path Indexed vector type field to search. - * @param BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represent the query vector. The number type - * must match the indexed field value type. + * @param Optional|BSONArray|Binary|PackedArray|array|string $queryVector Array of numbers or a BinData value that represents the query vector. The number type + * must match the indexed field value type. Required if `query` is not specified. * @param Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. * @param Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. * @param Optional|int $numCandidates This field is required if exact is false or omitted. @@ -100,18 +121,31 @@ final class VectorSearchStage implements InputStageInterface, OperatorInterface * @param Optional|bool $returnStoredSource If true, the search returns only the stored source fields configured on the index directly from the index and skips a full document lookup. If omitted, the default value is false. * @param Optional|Document|Serializable|array|stdClass $nestedOptions Configure how MongoDB Vector Search scores documents that contain nested arrays. * @param Optional|QueryInterface|array $parentFilter Any match query that compares an indexed top-level field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. Only valid if `nestedRoot` is specified in the index definition. + * @param Optional|string $query Natural language text query for automated embedding. MongoDB automatically + * generates a vector embedding for this text at query time using the embedding model + * configured in the index, or the `model` argument if specified. + * Required if `queryVector` is not specified. + * + * New in MongoDB 8.2 + * @param Optional|string $model The embedding model used to generate the query vector from the query text. If omitted, + * the model configured in the index definition is used. Must be compatible with the model + * used at index time. Only valid when `query` is specified. + * + * New in MongoDB 8.2 */ public function __construct( string $index, int $limit, string $path, - Binary|PackedArray|BSONArray|array|string $queryVector, + Optional|Binary|PackedArray|BSONArray|array|string $queryVector = Optional::Undefined, Optional|bool $exact = Optional::Undefined, Optional|QueryInterface|array $filter = Optional::Undefined, Optional|int $numCandidates = Optional::Undefined, Optional|bool $returnStoredSource = Optional::Undefined, Optional|Document|Serializable|stdClass|array $nestedOptions = Optional::Undefined, Optional|QueryInterface|array $parentFilter = Optional::Undefined, + Optional|string $query = Optional::Undefined, + Optional|string $model = Optional::Undefined, ) { $this->index = $index; $this->limit = $limit; @@ -135,5 +169,7 @@ public function __construct( } $this->parentFilter = $parentFilter; + $this->query = $query; + $this->model = $model; } } diff --git a/tests/Builder/Stage/Pipelines.php b/tests/Builder/Stage/Pipelines.php index 8d26ac4a5..95bcf2a3f 100644 --- a/tests/Builder/Stage/Pipelines.php +++ b/tests/Builder/Stage/Pipelines.php @@ -4465,4 +4465,83 @@ enum Pipelines: string } ] EXTENDED_JSON; + + /** + * Automated Embedding + * + * @see https://www.mongodb.com/docs/vector-search/crud-embeddings/automated-embedding/ + */ + case VectorSearchAutomatedEmbedding = <<<'EXTENDED_JSON' + [ + { + "$vectorSearch": { + "index": "vector_index", + "path": "plot_embedding", + "query": "time travel", + "numCandidates": { + "$numberInt": "150" + }, + "limit": { + "$numberInt": "10" + } + } + }, + { + "$project": { + "_id": { + "$numberInt": "0" + }, + "plot": { + "$numberInt": "1" + }, + "title": { + "$numberInt": "1" + }, + "score": { + "$meta": "vectorSearchScore" + } + } + } + ] + EXTENDED_JSON; + + /** + * Automated Embedding with model override + * + * @see https://www.mongodb.com/docs/vector-search/crud-embeddings/automated-embedding/ + */ + case VectorSearchAutomatedEmbeddingWithModelOverride = <<<'EXTENDED_JSON' + [ + { + "$vectorSearch": { + "index": "vector_index", + "path": "plot_embedding", + "query": "time travel", + "model": "voyage-3-lite", + "numCandidates": { + "$numberInt": "150" + }, + "limit": { + "$numberInt": "10" + } + } + }, + { + "$project": { + "_id": { + "$numberInt": "0" + }, + "plot": { + "$numberInt": "1" + }, + "title": { + "$numberInt": "1" + }, + "score": { + "$meta": "vectorSearchScore" + } + } + } + ] + EXTENDED_JSON; } diff --git a/tests/Builder/Stage/VectorSearchStageTest.php b/tests/Builder/Stage/VectorSearchStageTest.php index 088522895..326df8dca 100644 --- a/tests/Builder/Stage/VectorSearchStageTest.php +++ b/tests/Builder/Stage/VectorSearchStageTest.php @@ -64,6 +64,49 @@ public function testANNFilter(): void $this->assertSamePipeline(Pipelines::VectorSearchANNFilter, $pipeline); } + public function testAutomatedEmbedding(): void + { + $pipeline = new Pipeline( + Stage::vectorSearch( + index: 'vector_index', + limit: 10, + path: 'plot_embedding', + query: 'time travel', + numCandidates: 150, + ), + Stage::project( + _id: 0, + plot: 1, + title: 1, + score: ['$meta' => 'vectorSearchScore'], + ), + ); + + $this->assertSamePipeline(Pipelines::VectorSearchAutomatedEmbedding, $pipeline); + } + + public function testAutomatedEmbeddingWithModelOverride(): void + { + $pipeline = new Pipeline( + Stage::vectorSearch( + index: 'vector_index', + limit: 10, + path: 'plot_embedding', + query: 'time travel', + model: 'voyage-3-lite', + numCandidates: 150, + ), + Stage::project( + _id: 0, + plot: 1, + title: 1, + score: ['$meta' => 'vectorSearchScore'], + ), + ); + + $this->assertSamePipeline(Pipelines::VectorSearchAutomatedEmbeddingWithModelOverride, $pipeline); + } + public function testENN(): void { $pipeline = new Pipeline(