From 9fe3bd14e811baad66861c64379aad388ddd8a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 3 Dec 2024 20:10:22 +0100 Subject: [PATCH] Add generated files --- psalm-baseline.xml | 8 - src/Builder/Search/AutocompleteOperator.php | 76 + src/Builder/Search/CompoundOperator.php | 84 + .../Search/EmbeddedDocumentOperator.php | 57 + src/Builder/Search/EqualsOperator.php | 59 + src/Builder/Search/ExistsOperator.php | 48 + src/Builder/Search/FacetOperator.php | 49 + src/Builder/Search/FactoryTrait.php | 345 ++ src/Builder/Search/GeoShapeOperator.php | 62 + src/Builder/Search/GeoWithinOperator.php | 76 + src/Builder/Search/InOperator.php | 65 + src/Builder/Search/MoreLikeThisOperator.php | 52 + src/Builder/Search/NearOperator.php | 64 + src/Builder/Search/PhraseOperator.php | 83 + src/Builder/Search/QueryStringOperator.php | 40 + src/Builder/Search/RangeOperator.php | 85 + src/Builder/Search/RegexOperator.php | 67 + src/Builder/Search/TextOperator.php | 81 + src/Builder/Search/WildcardOperator.php | 66 + src/Builder/Stage/FactoryTrait.php | 77 +- src/Builder/Stage/FluentFactoryTrait.php | 79 +- src/Builder/Stage/SearchMetaStage.php | 35 +- src/Builder/Stage/SearchStage.php | 102 +- tests/Builder/Search/Pipelines.php | 2814 +++++++++++++++++ 24 files changed, 4530 insertions(+), 44 deletions(-) create mode 100644 src/Builder/Search/AutocompleteOperator.php create mode 100644 src/Builder/Search/CompoundOperator.php create mode 100644 src/Builder/Search/EmbeddedDocumentOperator.php create mode 100644 src/Builder/Search/EqualsOperator.php create mode 100644 src/Builder/Search/ExistsOperator.php create mode 100644 src/Builder/Search/FacetOperator.php create mode 100644 src/Builder/Search/FactoryTrait.php create mode 100644 src/Builder/Search/GeoShapeOperator.php create mode 100644 src/Builder/Search/GeoWithinOperator.php create mode 100644 src/Builder/Search/InOperator.php create mode 100644 src/Builder/Search/MoreLikeThisOperator.php create mode 100644 src/Builder/Search/NearOperator.php create mode 100644 src/Builder/Search/PhraseOperator.php create mode 100644 src/Builder/Search/QueryStringOperator.php create mode 100644 src/Builder/Search/RangeOperator.php create mode 100644 src/Builder/Search/RegexOperator.php create mode 100644 src/Builder/Search/TextOperator.php create mode 100644 src/Builder/Search/WildcardOperator.php create mode 100644 tests/Builder/Search/Pipelines.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index a06d5df23..321bbc05a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -60,9 +60,6 @@ - - recursiveEncode($val)]]> - @@ -73,19 +70,14 @@ - - - - recursiveEncode($val)]]> - diff --git a/src/Builder/Search/AutocompleteOperator.php b/src/Builder/Search/AutocompleteOperator.php new file mode 100644 index 000000000..19bdbf92d --- /dev/null +++ b/src/Builder/Search/AutocompleteOperator.php @@ -0,0 +1,76 @@ + 'path', + 'query' => 'query', + 'tokenOrder' => 'tokenOrder', + 'fuzzy' => 'fuzzy', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|string $tokenOrder */ + public readonly Optional|string $tokenOrder; + + /** @var Optional|Document|Serializable|array|stdClass $fuzzy */ + public readonly Optional|Document|Serializable|stdClass|array $fuzzy; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|string $tokenOrder + * @param Optional|Document|Serializable|array|stdClass $fuzzy + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|string $tokenOrder = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $fuzzy = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->tokenOrder = $tokenOrder; + $this->fuzzy = $fuzzy; + $this->score = $score; + } +} diff --git a/src/Builder/Search/CompoundOperator.php b/src/Builder/Search/CompoundOperator.php new file mode 100644 index 000000000..27b8c2aeb --- /dev/null +++ b/src/Builder/Search/CompoundOperator.php @@ -0,0 +1,84 @@ + 'must', + 'mustNot' => 'mustNot', + 'should' => 'should', + 'filter' => 'filter', + 'minimumShouldMatch' => 'minimumShouldMatch', + 'score' => 'score', + ]; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $must */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $must; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $mustNot */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $mustNot; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $should */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $should; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $filter */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $filter; + + /** @var Optional|int $minimumShouldMatch */ + public readonly Optional|int $minimumShouldMatch; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $must + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $mustNot + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $should + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $filter + * @param Optional|int $minimumShouldMatch + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $must = Optional::Undefined, + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $mustNot = Optional::Undefined, + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $should = Optional::Undefined, + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $filter = Optional::Undefined, + Optional|int $minimumShouldMatch = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->must = $must; + $this->mustNot = $mustNot; + $this->should = $should; + $this->filter = $filter; + $this->minimumShouldMatch = $minimumShouldMatch; + $this->score = $score; + } +} diff --git a/src/Builder/Search/EmbeddedDocumentOperator.php b/src/Builder/Search/EmbeddedDocumentOperator.php new file mode 100644 index 000000000..91f6c1f96 --- /dev/null +++ b/src/Builder/Search/EmbeddedDocumentOperator.php @@ -0,0 +1,57 @@ + 'path', 'operator' => 'operator', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Document|SearchOperatorInterface|Serializable|array|stdClass $operator */ + public readonly Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->operator = $operator; + $this->score = $score; + } +} diff --git a/src/Builder/Search/EqualsOperator.php b/src/Builder/Search/EqualsOperator.php new file mode 100644 index 000000000..bbfe75b8e --- /dev/null +++ b/src/Builder/Search/EqualsOperator.php @@ -0,0 +1,59 @@ + 'path', 'value' => 'value', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Binary|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value */ + public readonly Binary|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Binary|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Binary|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->value = $value; + $this->score = $score; + } +} diff --git a/src/Builder/Search/ExistsOperator.php b/src/Builder/Search/ExistsOperator.php new file mode 100644 index 000000000..4330f130f --- /dev/null +++ b/src/Builder/Search/ExistsOperator.php @@ -0,0 +1,48 @@ + 'path', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->score = $score; + } +} diff --git a/src/Builder/Search/FacetOperator.php b/src/Builder/Search/FacetOperator.php new file mode 100644 index 000000000..15fc10830 --- /dev/null +++ b/src/Builder/Search/FacetOperator.php @@ -0,0 +1,49 @@ + 'facets', 'operator' => 'operator']; + + /** @var Document|Serializable|array|stdClass $facets */ + public readonly Document|Serializable|stdClass|array $facets; + + /** @var Optional|Document|SearchOperatorInterface|Serializable|array|stdClass $operator */ + public readonly Optional|Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** + * @param Document|Serializable|array|stdClass $facets + * @param Optional|Document|SearchOperatorInterface|Serializable|array|stdClass $operator + */ + public function __construct( + Document|Serializable|stdClass|array $facets, + Optional|Document|Serializable|SearchOperatorInterface|stdClass|array $operator = Optional::Undefined, + ) { + $this->facets = $facets; + $this->operator = $operator; + } +} diff --git a/src/Builder/Search/FactoryTrait.php b/src/Builder/Search/FactoryTrait.php new file mode 100644 index 000000000..3a7762521 --- /dev/null +++ b/src/Builder/Search/FactoryTrait.php @@ -0,0 +1,345 @@ + 'path', 'relation' => 'relation', 'geometry' => 'geometry', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $relation */ + public readonly string $relation; + + /** @var Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $relation + * @param Document|GeometryInterface|Serializable|array|stdClass $geometry + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $relation, + Document|Serializable|GeometryInterface|stdClass|array $geometry, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->relation = $relation; + $this->geometry = $geometry; + $this->score = $score; + } +} diff --git a/src/Builder/Search/GeoWithinOperator.php b/src/Builder/Search/GeoWithinOperator.php new file mode 100644 index 000000000..dcf605697 --- /dev/null +++ b/src/Builder/Search/GeoWithinOperator.php @@ -0,0 +1,76 @@ + 'path', + 'box' => 'box', + 'circle' => 'circle', + 'geometry' => 'geometry', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Optional|Document|Serializable|array|stdClass $box */ + public readonly Optional|Document|Serializable|stdClass|array $box; + + /** @var Optional|Document|Serializable|array|stdClass $circle */ + public readonly Optional|Document|Serializable|stdClass|array $circle; + + /** @var Optional|Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Optional|Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Optional|Document|Serializable|array|stdClass $box + * @param Optional|Document|Serializable|array|stdClass $circle + * @param Optional|Document|GeometryInterface|Serializable|array|stdClass $geometry + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Optional|Document|Serializable|stdClass|array $box = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $circle = Optional::Undefined, + Optional|Document|Serializable|GeometryInterface|stdClass|array $geometry = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->box = $box; + $this->circle = $circle; + $this->geometry = $geometry; + $this->score = $score; + } +} diff --git a/src/Builder/Search/InOperator.php b/src/Builder/Search/InOperator.php new file mode 100644 index 000000000..f050a1679 --- /dev/null +++ b/src/Builder/Search/InOperator.php @@ -0,0 +1,65 @@ + 'path', 'value' => 'value', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var BSONArray|PackedArray|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly PackedArray|Type|BSONArray|stdClass|array|bool|float|int|null|string $value; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param BSONArray|PackedArray|Type|array|bool|float|int|null|stdClass|string $value + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + PackedArray|Type|BSONArray|stdClass|array|bool|float|int|null|string $value, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + $this->score = $score; + } +} diff --git a/src/Builder/Search/MoreLikeThisOperator.php b/src/Builder/Search/MoreLikeThisOperator.php new file mode 100644 index 000000000..689508d53 --- /dev/null +++ b/src/Builder/Search/MoreLikeThisOperator.php @@ -0,0 +1,52 @@ + 'like', 'score' => 'score']; + + /** @var BSONArray|Document|PackedArray|Serializable|array|stdClass $like */ + public readonly Document|PackedArray|Serializable|BSONArray|stdClass|array $like; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param BSONArray|Document|PackedArray|Serializable|array|stdClass $like + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + Document|PackedArray|Serializable|BSONArray|stdClass|array $like, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->like = $like; + $this->score = $score; + } +} diff --git a/src/Builder/Search/NearOperator.php b/src/Builder/Search/NearOperator.php new file mode 100644 index 000000000..ab1b9b0c1 --- /dev/null +++ b/src/Builder/Search/NearOperator.php @@ -0,0 +1,64 @@ + 'path', 'origin' => 'origin', 'pivot' => 'pivot', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Decimal128|Document|GeometryInterface|Int64|Serializable|UTCDateTime|array|float|int|stdClass $origin */ + public readonly Decimal128|Document|Int64|Serializable|UTCDateTime|GeometryInterface|stdClass|array|float|int $origin; + + /** @var Decimal128|Int64|float|int $pivot */ + public readonly Decimal128|Int64|float|int $pivot; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Decimal128|Document|GeometryInterface|Int64|Serializable|UTCDateTime|array|float|int|stdClass $origin + * @param Decimal128|Int64|float|int $pivot + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Decimal128|Document|Int64|Serializable|UTCDateTime|GeometryInterface|stdClass|array|float|int $origin, + Decimal128|Int64|float|int $pivot, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->origin = $origin; + $this->pivot = $pivot; + $this->score = $score; + } +} diff --git a/src/Builder/Search/PhraseOperator.php b/src/Builder/Search/PhraseOperator.php new file mode 100644 index 000000000..2bbb707a9 --- /dev/null +++ b/src/Builder/Search/PhraseOperator.php @@ -0,0 +1,83 @@ + 'path', + 'query' => 'query', + 'slop' => 'slop', + 'synonyms' => 'synonyms', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var BSONArray|PackedArray|array|string $query */ + public readonly PackedArray|BSONArray|array|string $query; + + /** @var Optional|int $slop */ + public readonly Optional|int $slop; + + /** @var Optional|string $synonyms */ + public readonly Optional|string $synonyms; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param BSONArray|PackedArray|array|string $query + * @param Optional|int $slop + * @param Optional|string $synonyms + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + PackedArray|BSONArray|array|string $query, + Optional|int $slop = Optional::Undefined, + Optional|string $synonyms = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + if (is_array($query) && ! array_is_list($query)) { + throw new InvalidArgumentException('Expected $query argument to be a list, got an associative array.'); + } + + $this->query = $query; + $this->slop = $slop; + $this->synonyms = $synonyms; + $this->score = $score; + } +} diff --git a/src/Builder/Search/QueryStringOperator.php b/src/Builder/Search/QueryStringOperator.php new file mode 100644 index 000000000..edc4d3471 --- /dev/null +++ b/src/Builder/Search/QueryStringOperator.php @@ -0,0 +1,40 @@ + 'defaultPath', 'query' => 'query']; + + /** @var array|string $defaultPath */ + public readonly array|string $defaultPath; + + /** @var string $query */ + public readonly string $query; + + /** + * @param array|string $defaultPath + * @param string $query + */ + public function __construct(array|string $defaultPath, string $query) + { + $this->defaultPath = $defaultPath; + $this->query = $query; + } +} diff --git a/src/Builder/Search/RangeOperator.php b/src/Builder/Search/RangeOperator.php new file mode 100644 index 000000000..a728d7477 --- /dev/null +++ b/src/Builder/Search/RangeOperator.php @@ -0,0 +1,85 @@ + 'path', + 'gt' => 'gt', + 'gte' => 'gte', + 'lt' => 'lt', + 'lte' => 'lte', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt */ + public readonly Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt; + + /** @var Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte */ + public readonly Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte; + + /** @var Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt */ + public readonly Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt; + + /** @var Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte */ + public readonly Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt + * @param Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte + * @param Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt + * @param Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt = Optional::Undefined, + Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte = Optional::Undefined, + Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt = Optional::Undefined, + Optional|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->gt = $gt; + $this->gte = $gte; + $this->lt = $lt; + $this->lte = $lte; + $this->score = $score; + } +} diff --git a/src/Builder/Search/RegexOperator.php b/src/Builder/Search/RegexOperator.php new file mode 100644 index 000000000..6b2c2d63a --- /dev/null +++ b/src/Builder/Search/RegexOperator.php @@ -0,0 +1,67 @@ + 'path', + 'query' => 'query', + 'allowAnalyzedField' => 'allowAnalyzedField', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|bool $allowAnalyzedField */ + public readonly Optional|bool $allowAnalyzedField; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|bool $allowAnalyzedField + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|bool $allowAnalyzedField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->allowAnalyzedField = $allowAnalyzedField; + $this->score = $score; + } +} diff --git a/src/Builder/Search/TextOperator.php b/src/Builder/Search/TextOperator.php new file mode 100644 index 000000000..4ade6b434 --- /dev/null +++ b/src/Builder/Search/TextOperator.php @@ -0,0 +1,81 @@ + 'path', + 'query' => 'query', + 'fuzzy' => 'fuzzy', + 'matchCriteria' => 'matchCriteria', + 'synonyms' => 'synonyms', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|Document|Serializable|array|stdClass $fuzzy */ + public readonly Optional|Document|Serializable|stdClass|array $fuzzy; + + /** @var Optional|string $matchCriteria */ + public readonly Optional|string $matchCriteria; + + /** @var Optional|string $synonyms */ + public readonly Optional|string $synonyms; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|Document|Serializable|array|stdClass $fuzzy + * @param Optional|string $matchCriteria + * @param Optional|string $synonyms + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|Document|Serializable|stdClass|array $fuzzy = Optional::Undefined, + Optional|string $matchCriteria = Optional::Undefined, + Optional|string $synonyms = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->fuzzy = $fuzzy; + $this->matchCriteria = $matchCriteria; + $this->synonyms = $synonyms; + $this->score = $score; + } +} diff --git a/src/Builder/Search/WildcardOperator.php b/src/Builder/Search/WildcardOperator.php new file mode 100644 index 000000000..ee481910e --- /dev/null +++ b/src/Builder/Search/WildcardOperator.php @@ -0,0 +1,66 @@ + 'path', + 'query' => 'query', + 'allowAnalyzedField' => 'allowAnalyzedField', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|bool $allowAnalyzedField */ + public readonly Optional|bool $allowAnalyzedField; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|bool $allowAnalyzedField + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|bool $allowAnalyzedField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->allowAnalyzedField = $allowAnalyzedField; + $this->score = $score; + } +} diff --git a/src/Builder/Stage/FactoryTrait.php b/src/Builder/Stage/FactoryTrait.php index 199cf64ef..5b1f47a8c 100644 --- a/src/Builder/Stage/FactoryTrait.php +++ b/src/Builder/Stage/FactoryTrait.php @@ -24,6 +24,7 @@ use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\QueryInterface; +use MongoDB\Builder\Type\SearchOperatorInterface; use MongoDB\Builder\Type\Sort; use MongoDB\Model\BSONArray; use stdClass; @@ -537,11 +538,35 @@ public static function sample(int $size): SampleStage * NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/search/ - * @param Document|Serializable|array|stdClass $search - */ - public static function search(Document|Serializable|stdClass|array $search): SearchStage - { - return new SearchStage($search); + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". + * @param Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. + * @param Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + * @param Optional|string $count Document that specifies the count options for retrieving a count of the results. + * @param Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. + * @param Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately following the specified reference point. + * @param Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. + * @param Optional|bool $returnStoredSource Flag that specifies whether to return the stored source document in the search results. If omitted, defaults to false.Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + * @param Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. + */ + public static function search( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $highlight = Optional::Undefined, + Optional|bool $concurrent = Optional::Undefined, + Optional|string $count = Optional::Undefined, + Optional|string $searchAfter = Optional::Undefined, + Optional|string $searchBefore = Optional::Undefined, + Optional|bool $scoreDetails = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sort = Optional::Undefined, + Optional|bool $returnStoredSource = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $tracking = Optional::Undefined, + ): SearchStage { + return new SearchStage($operator, $index, $highlight, $concurrent, $count, $searchAfter, $searchBefore, $scoreDetails, $sort, $returnStoredSource, $tracking); } /** @@ -549,11 +574,17 @@ public static function search(Document|Serializable|stdClass|array $search): Sea * NOTE: $searchMeta is only available for MongoDB Atlas clusters running MongoDB v4.4.9 or higher, and is not available for self-managed deployments. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/searchMeta/ - * @param Document|Serializable|array|stdClass $meta - */ - public static function searchMeta(Document|Serializable|stdClass|array $meta): SearchMetaStage - { - return new SearchMetaStage($meta); + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + */ + public static function searchMeta( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + ): SearchMetaStage { + return new SearchMetaStage($operator, $index, $count); } /** @@ -678,4 +709,30 @@ public static function unwind( ): UnwindStage { return new UnwindStage($path, $includeArrayIndex, $preserveNullAndEmptyArrays); } + + /** + * The $vectorSearch stage performs an ANN or ENN search on a vector in the specified field. + * + * @see https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/ + * @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 array|string $path Indexed vector type field to search. + * @param BSONArray|PackedArray|array $queryVector Array of numbers that represent the query vector. The number type must match the indexed field value type. + * @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 + * @param Optional|int $numCandidates + */ + public static function vectorSearch( + string $index, + int $limit, + array|string $path, + PackedArray|BSONArray|array $queryVector, + Optional|bool $exact = Optional::Undefined, + Optional|QueryInterface|array $filter = Optional::Undefined, + Optional|int $numCandidates = Optional::Undefined, + ): VectorSearchStage { + return new VectorSearchStage($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates); + } } diff --git a/src/Builder/Stage/FluentFactoryTrait.php b/src/Builder/Stage/FluentFactoryTrait.php index 6f468322d..e2858bdde 100644 --- a/src/Builder/Stage/FluentFactoryTrait.php +++ b/src/Builder/Stage/FluentFactoryTrait.php @@ -26,6 +26,7 @@ use MongoDB\Builder\Type\FieldQueryInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\QueryInterface; +use MongoDB\Builder\Type\SearchOperatorInterface; use MongoDB\Builder\Type\Sort; use MongoDB\Builder\Type\StageInterface; use MongoDB\Model\BSONArray; @@ -605,11 +606,35 @@ public function sample(int $size): static * NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/search/ - * @param Document|Serializable|array|stdClass $search - */ - public function search(Document|Serializable|stdClass|array $search): static - { - $this->pipeline[] = Stage::search($search); + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". + * @param Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. + * @param Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + * @param Optional|string $count Document that specifies the count options for retrieving a count of the results. + * @param Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. + * @param Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately following the specified reference point. + * @param Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. + * @param Optional|bool $returnStoredSource Flag that specifies whether to return the stored source document in the search results. If omitted, defaults to false.Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + * @param Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. + */ + public function search( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $highlight = Optional::Undefined, + Optional|bool $concurrent = Optional::Undefined, + Optional|string $count = Optional::Undefined, + Optional|string $searchAfter = Optional::Undefined, + Optional|string $searchBefore = Optional::Undefined, + Optional|bool $scoreDetails = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sort = Optional::Undefined, + Optional|bool $returnStoredSource = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $tracking = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::search($operator, $index, $highlight, $concurrent, $count, $searchAfter, $searchBefore, $scoreDetails, $sort, $returnStoredSource, $tracking); return $this; } @@ -619,11 +644,17 @@ public function search(Document|Serializable|stdClass|array $search): static * NOTE: $searchMeta is only available for MongoDB Atlas clusters running MongoDB v4.4.9 or higher, and is not available for self-managed deployments. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/searchMeta/ - * @param Document|Serializable|array|stdClass $meta - */ - public function searchMeta(Document|Serializable|stdClass|array $meta): static - { - $this->pipeline[] = Stage::searchMeta($meta); + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + */ + public function searchMeta( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::searchMeta($operator, $index, $count); return $this; } @@ -767,4 +798,32 @@ public function unwind( return $this; } + + /** + * The $vectorSearch stage performs an ANN or ENN search on a vector in the specified field. + * + * @see https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/ + * @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 array|string $path Indexed vector type field to search. + * @param BSONArray|PackedArray|array $queryVector Array of numbers that represent the query vector. The number type must match the indexed field value type. + * @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 + * @param Optional|int $numCandidates + */ + public function vectorSearch( + string $index, + int $limit, + array|string $path, + PackedArray|BSONArray|array $queryVector, + Optional|bool $exact = Optional::Undefined, + Optional|QueryInterface|array $filter = Optional::Undefined, + Optional|int $numCandidates = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::vectorSearch($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates); + + return $this; + } } diff --git a/src/Builder/Stage/SearchMetaStage.php b/src/Builder/Stage/SearchMetaStage.php index 88f05bec1..14687161b 100644 --- a/src/Builder/Stage/SearchMetaStage.php +++ b/src/Builder/Stage/SearchMetaStage.php @@ -12,6 +12,8 @@ use MongoDB\BSON\Serializable; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Builder\Type\Optional; +use MongoDB\Builder\Type\SearchOperatorInterface; use MongoDB\Builder\Type\StageInterface; use stdClass; @@ -24,18 +26,35 @@ */ final class SearchMetaStage implements StageInterface, OperatorInterface { - public const ENCODE = Encode::Single; + public const ENCODE = Encode::Object; public const NAME = '$searchMeta'; - public const PROPERTIES = ['meta' => 'meta']; + public const PROPERTIES = ['operator' => null, 'index' => 'index', 'count' => 'count']; - /** @var Document|Serializable|array|stdClass $meta */ - public readonly Document|Serializable|stdClass|array $meta; + /** + * @var Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + */ + public readonly Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** @var Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. */ + public readonly Optional|string $index; + + /** @var Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. */ + public readonly Optional|Document|Serializable|stdClass|array $count; /** - * @param Document|Serializable|array|stdClass $meta + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. */ - public function __construct(Document|Serializable|stdClass|array $meta) - { - $this->meta = $meta; + public function __construct( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + ) { + $this->operator = $operator; + $this->index = $index; + $this->count = $count; } } diff --git a/src/Builder/Stage/SearchStage.php b/src/Builder/Stage/SearchStage.php index 188a2ece4..ec1ae8030 100644 --- a/src/Builder/Stage/SearchStage.php +++ b/src/Builder/Stage/SearchStage.php @@ -12,6 +12,8 @@ use MongoDB\BSON\Serializable; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Builder\Type\Optional; +use MongoDB\Builder\Type\SearchOperatorInterface; use MongoDB\Builder\Type\StageInterface; use stdClass; @@ -24,18 +26,102 @@ */ final class SearchStage implements StageInterface, OperatorInterface { - public const ENCODE = Encode::Single; + public const ENCODE = Encode::Object; public const NAME = '$search'; - public const PROPERTIES = ['search' => 'search']; - /** @var Document|Serializable|array|stdClass $search */ - public readonly Document|Serializable|stdClass|array $search; + public const PROPERTIES = [ + 'operator' => null, + 'index' => 'index', + 'highlight' => 'highlight', + 'concurrent' => 'concurrent', + 'count' => 'count', + 'searchAfter' => 'searchAfter', + 'searchBefore' => 'searchBefore', + 'scoreDetails' => 'scoreDetails', + 'sort' => 'sort', + 'returnStoredSource' => 'returnStoredSource', + 'tracking' => 'tracking', + ]; /** - * @param Document|Serializable|array|stdClass $search + * @var Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. */ - public function __construct(Document|Serializable|stdClass|array $search) - { - $this->search = $search; + public readonly Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** @var Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". */ + public readonly Optional|string $index; + + /** @var Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. */ + public readonly Optional|Document|Serializable|stdClass|array $highlight; + + /** + * @var Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + */ + public readonly Optional|bool $concurrent; + + /** @var Optional|string $count Document that specifies the count options for retrieving a count of the results. */ + public readonly Optional|string $count; + + /** @var Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. */ + public readonly Optional|string $searchAfter; + + /** @var Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately following the specified reference point. */ + public readonly Optional|string $searchBefore; + + /** @var Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. */ + public readonly Optional|bool $scoreDetails; + + /** @var Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. */ + public readonly Optional|Document|Serializable|stdClass|array $sort; + + /** @var Optional|bool $returnStoredSource Flag that specifies whether to return the stored source document in the search results. If omitted, defaults to false.Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. */ + public readonly Optional|bool $returnStoredSource; + + /** @var Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. */ + public readonly Optional|Document|Serializable|stdClass|array $tracking; + + /** + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". + * @param Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. + * @param Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + * @param Optional|string $count Document that specifies the count options for retrieving a count of the results. + * @param Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. + * @param Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately following the specified reference point. + * @param Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. + * @param Optional|bool $returnStoredSource Flag that specifies whether to return the stored source document in the search results. If omitted, defaults to false.Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + * @param Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. + */ + public function __construct( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $highlight = Optional::Undefined, + Optional|bool $concurrent = Optional::Undefined, + Optional|string $count = Optional::Undefined, + Optional|string $searchAfter = Optional::Undefined, + Optional|string $searchBefore = Optional::Undefined, + Optional|bool $scoreDetails = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sort = Optional::Undefined, + Optional|bool $returnStoredSource = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $tracking = Optional::Undefined, + ) { + $this->operator = $operator; + $this->index = $index; + $this->highlight = $highlight; + $this->concurrent = $concurrent; + $this->count = $count; + $this->searchAfter = $searchAfter; + $this->searchBefore = $searchBefore; + $this->scoreDetails = $scoreDetails; + $this->sort = $sort; + $this->returnStoredSource = $returnStoredSource; + $this->tracking = $tracking; } } diff --git a/tests/Builder/Search/Pipelines.php b/tests/Builder/Search/Pipelines.php new file mode 100644 index 000000000..fa94f8c9a --- /dev/null +++ b/tests/Builder/Search/Pipelines.php @@ -0,0 +1,2814 @@ +