-
Notifications
You must be signed in to change notification settings - Fork 1.5k
PHPORM-275 PHPORM-276 Add Query\Builder::search()
and autocomplete()
#3232
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
fc2ec05
fc5c0b7
5291e7c
4d08755
ed5c8f7
6abce65
715c130
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 |
---|---|---|
|
@@ -5,7 +5,10 @@ | |
namespace MongoDB\Laravel\Eloquent; | ||
|
||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; | ||
use Illuminate\Database\Eloquent\Collection; | ||
use Illuminate\Database\Eloquent\Model; | ||
use MongoDB\BSON\Document; | ||
use MongoDB\Builder\Type\SearchOperatorInterface; | ||
use MongoDB\Driver\CursorInterface; | ||
use MongoDB\Driver\Exception\WriteException; | ||
use MongoDB\Laravel\Connection; | ||
|
@@ -21,7 +24,10 @@ | |
use function iterator_to_array; | ||
use function property_exists; | ||
|
||
/** @method \MongoDB\Laravel\Query\Builder toBase() */ | ||
/** | ||
* @method \MongoDB\Laravel\Query\Builder toBase() | ||
* @template TModel of Model | ||
*/ | ||
class Builder extends EloquentBuilder | ||
{ | ||
private const DUPLICATE_KEY_ERROR = 11000; | ||
|
@@ -49,6 +55,7 @@ class Builder extends EloquentBuilder | |
'insertusing', | ||
'max', | ||
'min', | ||
'autocomplete', | ||
'pluck', | ||
'pull', | ||
'push', | ||
|
@@ -69,6 +76,31 @@ public function aggregate($function = null, $columns = ['*']) | |
return $result ?: $this; | ||
} | ||
|
||
/** | ||
* Performs a full-text search of the field or fields in an Atlas collection. | ||
* | ||
* @see https://www.mongodb.com/docs/atlas/atlas-search/aggregation-stages/search/ | ||
* | ||
* @return Collection<int, TModel> | ||
*/ | ||
public function search( | ||
SearchOperatorInterface|array $operator, | ||
?string $index = null, | ||
?array $highlight = null, | ||
?bool $concurrent = null, | ||
?string $count = null, | ||
?string $searchAfter = null, | ||
?string $searchBefore = null, | ||
?bool $scoreDetails = null, | ||
?array $sort = null, | ||
?bool $returnStoredSource = null, | ||
?array $tracking = null, | ||
): Collection { | ||
$results = $this->toBase()->search($operator, $index, $highlight, $concurrent, $count, $searchAfter, $searchBefore, $scoreDetails, $sort, $returnStoredSource, $tracking); | ||
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 noted the Noted this probably has nothing to do with the PR, so feel free to ignore this complaint. |
||
|
||
return $this->model->hydrate($results->all()); | ||
} | ||
|
||
/** @inheritdoc */ | ||
public function update(array $values, array $options = []) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,13 +23,16 @@ | |
use MongoDB\BSON\ObjectID; | ||
use MongoDB\BSON\Regex; | ||
use MongoDB\BSON\UTCDateTime; | ||
use MongoDB\Builder\Search; | ||
use MongoDB\Builder\Stage\FluentFactoryTrait; | ||
use MongoDB\Builder\Type\SearchOperatorInterface; | ||
use MongoDB\Driver\Cursor; | ||
use Override; | ||
use RuntimeException; | ||
use stdClass; | ||
|
||
use function array_fill_keys; | ||
use function array_filter; | ||
use function array_is_list; | ||
use function array_key_exists; | ||
use function array_map; | ||
|
@@ -1490,6 +1493,68 @@ public function options(array $options) | |
return $this; | ||
} | ||
|
||
/** | ||
* Performs a full-text search of the field or fields in an Atlas collection. | ||
* NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. | ||
* | ||
* @see https://www.mongodb.com/docs/atlas/atlas-search/aggregation-stages/search/ | ||
* | ||
* @return Collection<object|array> | ||
*/ | ||
public function search( | ||
SearchOperatorInterface|array $operator, | ||
?string $index = null, | ||
?array $highlight = null, | ||
?bool $concurrent = null, | ||
?string $count = null, | ||
?string $searchAfter = null, | ||
?string $searchBefore = null, | ||
?bool $scoreDetails = null, | ||
?array $sort = null, | ||
?bool $returnStoredSource = null, | ||
?array $tracking = null, | ||
): Collection { | ||
// Forward named arguments to the search stage, skip null values | ||
$args = array_filter([ | ||
'operator' => $operator, | ||
'index' => $index, | ||
'highlight' => $highlight, | ||
'concurrent' => $concurrent, | ||
'count' => $count, | ||
'searchAfter' => $searchAfter, | ||
'searchBefore' => $searchBefore, | ||
'scoreDetails' => $scoreDetails, | ||
'sort' => $sort, | ||
'returnStoredSource' => $returnStoredSource, | ||
'tracking' => $tracking, | ||
], fn ($arg) => $arg !== null); | ||
|
||
return $this->aggregate()->search(...$args)->get(); | ||
} | ||
|
||
/** | ||
* Performs an autocomplete search of the field using an Atlas Search index. | ||
* NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. | ||
* You must create an Atlas Search index with an autocomplete configuration before you can use this stage. | ||
* | ||
* @see https://www.mongodb.com/docs/atlas/atlas-search/autocomplete/ | ||
* | ||
* @return Collection<string> | ||
*/ | ||
public function autocomplete(string $path, string $query, bool|array $fuzzy = false, string $tokenOrder = 'any'): Collection | ||
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 you're going to document 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 think this would benefit from a docs link, like you did for |
||
{ | ||
$args = ['path' => $path, 'query' => $query, 'tokenOrder' => $tokenOrder]; | ||
if ($fuzzy === true) { | ||
$args['fuzzy'] = ['maxEdits' => 2]; | ||
} elseif ($fuzzy !== false) { | ||
$args['fuzzy'] = $fuzzy; | ||
} | ||
|
||
return $this->aggregate()->search( | ||
Search::autocomplete(...$args), | ||
)->get()->pluck($path); | ||
} | ||
|
||
/** | ||
* Apply the connection's session to options if it's not already specified. | ||
*/ | ||
|
Uh oh!
There was an error while loading. Please reload this page.