Skip to content

Commit 9a8932c

Browse files
committed
Implement autocomplete
1 parent 4f55f79 commit 9a8932c

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

src/Eloquent/Builder.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace MongoDB\Laravel\Eloquent;
66

77
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
8+
use Illuminate\Support\Collection;
89
use MongoDB\BSON\Document;
910
use MongoDB\Driver\CursorInterface;
1011
use MongoDB\Driver\Exception\WriteException;
@@ -16,6 +17,7 @@
1617
use function array_key_exists;
1718
use function array_merge;
1819
use function collect;
20+
use function compact;
1921
use function is_array;
2022
use function is_object;
2123
use function iterator_to_array;
@@ -69,6 +71,18 @@ public function aggregate($function = null, $columns = ['*'])
6971
return $result ?: $this;
7072
}
7173

74+
public function search(...$args)
75+
{
76+
$results = $this->toBase()->search(...$args);
77+
78+
return $this->model->hydrate($results->all());
79+
}
80+
81+
public function autocomplete(string $path, string $query, bool|array $fuzzy = false, string $tokenOrder = 'any'): Collection
82+
{
83+
return $this->toBase()->autocomplete(...compact('path', 'query', 'fuzzy', 'tokenOrder'));
84+
}
85+
7286
/** @inheritdoc */
7387
public function update(array $values, array $options = [])
7488
{

src/Query/Builder.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use MongoDB\BSON\ObjectID;
2424
use MongoDB\BSON\Regex;
2525
use MongoDB\BSON\UTCDateTime;
26+
use MongoDB\Builder\Search;
2627
use MongoDB\Builder\Stage\FluentFactoryTrait;
2728
use MongoDB\Builder\Type\SearchOperatorInterface;
2829
use MongoDB\Driver\Cursor;
@@ -41,6 +42,7 @@
4142
use function blank;
4243
use function call_user_func;
4344
use function call_user_func_array;
45+
use function compact;
4446
use function count;
4547
use function ctype_xdigit;
4648
use function date_default_timezone_get;
@@ -1522,10 +1524,23 @@ public function search(
15221524
?array $sort = null,
15231525
?bool $returnStoredSource = null,
15241526
?array $tracking = null,
1525-
): Collection|LazyCollection {
1526-
return $this->aggregate()
1527-
->search(...array_filter(func_get_args(), fn ($arg) => $arg !== null))
1528-
->get();
1527+
): Collection {
1528+
return $this->aggregate()->search(...array_filter(func_get_args(), fn ($arg) => $arg !== null))->get();
1529+
}
1530+
1531+
/** @return Collection<string> */
1532+
public function autocomplete(string $path, string $query, bool|array $fuzzy = false, string $tokenOrder = 'any'): Collection
1533+
{
1534+
$args = compact('path', 'query', 'fuzzy', 'tokenOrder');
1535+
if ($args['fuzzy'] === true) {
1536+
$args['fuzzy'] = ['maxEdits' => 2];
1537+
} elseif ($args['fuzzy'] === false) {
1538+
unset($args['fuzzy']);
1539+
}
1540+
1541+
return $this->aggregate()->search(
1542+
Search::autocomplete(...$args),
1543+
)->get()->pluck($path);
15291544
}
15301545

15311546
/**

tests/AtlasSearchTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace MongoDB\Laravel\Tests;
44

5+
use Illuminate\Database\Eloquent\Collection;
56
use Illuminate\Support\Facades\Schema;
7+
use MongoDB\Builder\Search;
68
use MongoDB\Collection as MongoDBCollection;
79
use MongoDB\Driver\Exception\ServerException;
810
use MongoDB\Laravel\Schema\Builder;
@@ -42,6 +44,7 @@ public function setUp(): void
4244
]);
4345

4446
$collection = $this->getConnection('mongodb')->getCollection('books');
47+
4548
assert($collection instanceof MongoDBCollection);
4649
try {
4750
$collection->createSearchIndex([
@@ -135,4 +138,60 @@ public function testGetIndexes()
135138

136139
self::assertSame($expected, $indexes);
137140
}
141+
142+
public function testEloquentBuilderSearch()
143+
{
144+
$results = Book::search(Search::text('title', 'systems'));
145+
146+
self::assertInstanceOf(Collection::class, $results);
147+
self::assertCount(3, $results);
148+
self::assertInstanceOf(Book::class, $results->first());
149+
self::assertSame([
150+
'Operating System Concepts',
151+
'Database System Concepts',
152+
'Modern Operating Systems',
153+
], $results->pluck('title')->all());
154+
}
155+
156+
public function testDatabaseBuilderSearch()
157+
{
158+
$results = $this->getConnection('mongodb')->table('books')
159+
->search(Search::text('title', 'systems'));
160+
161+
self::assertInstanceOf(\Illuminate\Support\Collection::class, $results);
162+
self::assertCount(3, $results);
163+
self::assertIsArray($results->first());
164+
self::assertSame([
165+
'Operating System Concepts',
166+
'Database System Concepts',
167+
'Modern Operating Systems',
168+
], $results->pluck('title')->all());
169+
}
170+
171+
public function testEloquentBuilderAutocomplete()
172+
{
173+
$results = Book::autocomplete('title', 'system');
174+
175+
self::assertInstanceOf(\Illuminate\Support\Collection::class, $results);
176+
self::assertCount(3, $results);
177+
self::assertSame([
178+
'Operating System Concepts',
179+
'Database System Concepts',
180+
'Modern Operating Systems',
181+
], $results->all());
182+
}
183+
184+
public function testDatabaseBuilderAutocomplete()
185+
{
186+
$results = $this->getConnection('mongodb')->table('books')
187+
->autocomplete('title', 'system');
188+
189+
self::assertInstanceOf(\Illuminate\Support\Collection::class, $results);
190+
self::assertCount(3, $results);
191+
self::assertSame([
192+
'Operating System Concepts',
193+
'Database System Concepts',
194+
'Modern Operating Systems',
195+
], $results->all());
196+
}
138197
}

0 commit comments

Comments
 (0)