-
Notifications
You must be signed in to change notification settings - Fork 4
PHPLIB-1363 PHPLIB-1355 Add enum for $type
query and $meta
expression
#38
Changes from all commits
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 |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace MongoDB\Builder; | ||
|
||
use MongoDB\Builder\Type\Encode; | ||
use MongoDB\Builder\Type\ExpressionInterface; | ||
use MongoDB\Builder\Type\OperatorInterface; | ||
|
||
/** | ||
* Returns the metadata associated with a document, e.g. "textScore" when performing text search. | ||
* | ||
* @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta/ | ||
*/ | ||
enum Meta: string implements OperatorInterface, ExpressionInterface | ||
{ | ||
public const ENCODE = Encode::Single; | ||
|
||
/** | ||
* Returns the score associated with the corresponding $text query for each | ||
* matching document. The text score signifies how well the document matched | ||
* the search term or terms. | ||
*/ | ||
case TextScore = 'textScore'; | ||
|
||
/** | ||
* Returns an index key for the document if a non-text index is used. The | ||
* { $meta: "indexKey" } expression is for debugging purposes only, and | ||
* not for application logic, and is preferred over cursor.returnKey(). | ||
*/ | ||
case IndexKey = 'indexKey'; | ||
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. Do the cases here preclude users from using this with additional modes? $meta: Definition mentions searchScore and searchHighlights for Atlas. |
||
|
||
/** | ||
* Display search terms in their original context. | ||
*/ | ||
case SearchHighlights = 'searchHighlights'; | ||
|
||
public function getOperator(): string | ||
{ | ||
return '$meta'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace MongoDB\Builder; | ||
|
||
use MongoDB\Builder\Query\TypeOperator; | ||
use MongoDB\Builder\Type\Encode; | ||
use MongoDB\Builder\Type\FieldQueryInterface; | ||
use MongoDB\Builder\Type\OperatorInterface; | ||
|
||
/** | ||
* Shortcut for $type field query operator | ||
* | ||
* @see https://www.mongodb.com/docs/manual/reference/operator/query/type/#available-types | ||
* @see TypeOperator | ||
*/ | ||
enum QueryType: string implements OperatorInterface, FieldQueryInterface | ||
{ | ||
public const ENCODE = Encode::Array; | ||
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. Is this the first time a BackedEnum is being used for an encoding type? If so, perhaps it'd be prudent to have That would address my question about how a BackedEnum might be handled for other 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. We need to rework the whole encoder class. The "ENCODE" constant will not stay, it may become a method of the Operator interface. 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. If this isn't already ticketed please do so and drop a reference to the issue. |
||
|
||
case Array = 'array'; | ||
case Binary = 'binData'; | ||
case Bool = 'bool'; | ||
case Decimal64 = 'double'; | ||
case Decimal128 = 'decimal'; | ||
case Int32 = 'int'; | ||
case Int64 = 'long'; | ||
case Javascript = 'javascript'; | ||
case Object = 'object'; | ||
case ObjectId = 'objectId'; | ||
case MaxKey = 'maxKey'; | ||
case MinKey = 'minKey'; | ||
case Null = 'null'; | ||
/** Alias for Int32, Int64, Decimal64, Decimal128 */ | ||
case Number = 'number'; | ||
case Regex = 'regex'; | ||
case String = 'string'; | ||
case Timestamp = 'timestamp'; | ||
case UTCDateTime = 'date'; | ||
|
||
public function getOperator(): string | ||
{ | ||
return '$type'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace MongoDB\Tests\Builder\Expression; | ||
|
||
use MongoDB\Builder\Accumulator; | ||
use MongoDB\Builder\Expression; | ||
use MongoDB\Builder\Meta; | ||
use MongoDB\Builder\Pipeline; | ||
use MongoDB\Builder\Query; | ||
use MongoDB\Builder\Stage; | ||
use MongoDB\Tests\Builder\PipelineTestCase; | ||
|
||
/** | ||
* Test $meta expression | ||
*/ | ||
class MetaOperatorTest extends PipelineTestCase | ||
{ | ||
public function testIndexKey(): void | ||
{ | ||
$pipeline = new Pipeline( | ||
Stage::match( | ||
type: 'apparel', | ||
), | ||
Stage::addFields( | ||
idxKey: Expression::meta('indexKey'), | ||
), | ||
); | ||
|
||
$this->assertSamePipeline(Pipelines::MetaIndexKey, $pipeline); | ||
} | ||
|
||
public function testIndexKeyWithEnum(): void | ||
{ | ||
$pipeline = new Pipeline( | ||
Stage::match( | ||
type: 'apparel', | ||
), | ||
Stage::addFields( | ||
idxKey: Meta::IndexKey, | ||
), | ||
); | ||
|
||
$this->assertSamePipeline(Pipelines::MetaIndexKey, $pipeline); | ||
} | ||
|
||
public function testTextScore(): void | ||
{ | ||
$pipeline = new Pipeline( | ||
Stage::match( | ||
Query::text('cake'), | ||
), | ||
Stage::group( | ||
_id: Expression::meta('textScore'), | ||
count: Accumulator::sum(1), | ||
), | ||
); | ||
|
||
$this->assertSamePipeline(Pipelines::MetaTextScore, $pipeline); | ||
} | ||
|
||
public function testTextScoreWithEnum(): void | ||
{ | ||
$pipeline = new Pipeline( | ||
Stage::match( | ||
Query::text('cake'), | ||
), | ||
Stage::group( | ||
_id: Meta::TextScore, | ||
count: Accumulator::sum(1), | ||
), | ||
); | ||
|
||
$this->assertSamePipeline(Pipelines::MetaTextScore, $pipeline); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
|
||
use MongoDB\Builder\Pipeline; | ||
use MongoDB\Builder\Query; | ||
use MongoDB\Builder\QueryType; | ||
use MongoDB\Builder\Stage; | ||
use MongoDB\Tests\Builder\PipelineTestCase; | ||
|
||
|
@@ -32,16 +33,16 @@ public function testQueryingByDataType(): void | |
zipCode: Query::type(2), | ||
), | ||
Stage::match( | ||
zipCode: Query::type('string'), | ||
zipCode: QueryType::String, | ||
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. Huh, this is interesting. I had initially considered using an enum case as the argument for 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. I can customize the 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. Not sure if that is necessary. This allows people to do whatever they want with the 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. I assume this only works because QueryType is both an enum and an OperatorInterface (and FieldQueryInterface in that it's associated with a field path). I assume this convenience only works for a single type check, though. Trying to match And that's where |
||
), | ||
Stage::match( | ||
zipCode: Query::type(1), | ||
), | ||
Stage::match( | ||
zipCode: Query::type('double'), | ||
zipCode: Query::type(QueryType::Decimal64), | ||
), | ||
Stage::match( | ||
zipCode: Query::type('number'), | ||
zipCode: QueryType::Number, | ||
), | ||
); | ||
|
||
|
@@ -69,7 +70,7 @@ public function testQueryingByMultipleDataType(): void | |
zipCode: Query::type(2, 1), | ||
), | ||
Stage::match( | ||
zipCode: Query::type('string', 'double'), | ||
zipCode: Query::type(QueryType::String, 'double'), | ||
), | ||
); | ||
|
||
|
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.
@alcaeus suggested to name it
SortMeta
. #56 (comment)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.
$meta: Behavior suggests the operator can be used in context beyond sorting, such as projections.
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.
The
ExpressionInterface
allows to use it anywhere an expression is expected.