Skip to content

Commit 5c8a818

Browse files
committed
Create search example
1 parent f6ce211 commit 5c8a818

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

examples/atlas-search.php

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?php
2+
3+
/**
4+
* This example demonstrates how to create an Atlas Search index and perform a search query.
5+
* It requires a MongoDB Atlas M10+ cluster with Sample Dataset loaded.
6+
*
7+
* Use the MONGODB_URI environment variable to specify the connection string from the Atlas UI.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace MongoDB\Examples;
13+
14+
use Closure;
15+
use MongoDB\Client;
16+
use RuntimeException;
17+
18+
use function define;
19+
use function getenv;
20+
use function hrtime;
21+
use function iterator_to_array;
22+
use function sleep;
23+
use function str_contains;
24+
25+
require __DIR__ . '/../vendor/autoload.php';
26+
27+
$uri = getenv('MONGODB_URI');
28+
if (! $uri || ! str_contains($uri, '.mongodb.net')) {
29+
echo 'This example requires a MongoDB Atlas cluster.', "\n";
30+
echo 'Make sure you set the MONGODB_URI environment variable.', "\n";
31+
exit(1);
32+
}
33+
34+
// Atlas Search index management operations are asynchronous.
35+
// They usually take less than 5 minutes to complete.
36+
define('WAIT_TIMEOUT_SEC', 300);
37+
38+
$client = new Client($uri);
39+
$collection = $client->selectCollection('sample_airbnb', 'listingsAndReviews');
40+
41+
$count = $collection->estimatedDocumentCount();
42+
if ($count === 0) {
43+
echo 'This example requires the sample_airbnb database with the listingsAndReviews collection.', "\n";
44+
echo 'Load the sample dataset in your MongoDB Atlas cluster before running this example:', "\n";
45+
echo ' https://www.mongodb.com/docs/atlas/sample-data/', "\n";
46+
exit(1);
47+
}
48+
49+
// Delete the index if it already exists
50+
$indexes = iterator_to_array($collection->listSearchIndexes());
51+
foreach ($indexes as $index) {
52+
if ($index->name === 'default') {
53+
echo "\nThe index already exists. Dropping it.\n";
54+
$collection->dropSearchIndex($index->name);
55+
56+
// Wait for the index to be deleted.
57+
wait(function () use ($collection) {
58+
foreach ($collection->listSearchIndexes() as $index) {
59+
if ($index->name === 'default') {
60+
echo '.';
61+
62+
return false;
63+
}
64+
}
65+
66+
echo "\n";
67+
68+
return true;
69+
});
70+
}
71+
}
72+
73+
// Create the search index
74+
echo "\nCreating the index.\n";
75+
$collection->createSearchIndex(
76+
/* The index definition requires a mapping
77+
* See: https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/ */
78+
['mappings' => ['dynamic' => true]],
79+
// "default" is the default index name, this config can be omitted.
80+
['name' => 'default'],
81+
);
82+
83+
// Wait for the index to be ready.
84+
wait(function () use ($collection) {
85+
foreach ($collection->listSearchIndexes() as $index) {
86+
if ($index->name === 'default') {
87+
echo '.';
88+
89+
return $index->queryable;
90+
}
91+
}
92+
93+
return false;
94+
});
95+
96+
// Perform a text search
97+
echo "\n", 'Performing a text search...', "\n";
98+
$results = $collection->aggregate([
99+
[
100+
'$search' => [
101+
'index' => 'default',
102+
'text' => [
103+
'query' => 'view beach ocean',
104+
'path' => ['name'],
105+
],
106+
],
107+
],
108+
['$project' => ['name' => 1, 'description' => 1]],
109+
['$limit' => 10],
110+
])->toArray();
111+
112+
foreach ($results as $document) {
113+
echo ' -', $document['name'], "\n";
114+
}
115+
116+
echo "\n", 'Enjoy MongoDB Atlas Search!', "\n\n";
117+
118+
/**
119+
* This function waits until the callback returns true or the timeout is reached.
120+
*
121+
* @param Closure():bool $callback
122+
*/
123+
function wait(Closure $callback): void
124+
{
125+
$timeout = hrtime()[0] + WAIT_TIMEOUT_SEC;
126+
while (hrtime()[0] < $timeout) {
127+
if ($callback()) {
128+
return;
129+
}
130+
131+
sleep(5);
132+
}
133+
134+
throw new RuntimeException('Time out');
135+
}

psalm-baseline.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@
55
<code><![CDATA[$clientEncryption->decrypt($document->encryptedField)]]></code>
66
</MixedArgument>
77
</file>
8+
<file src="examples/atlas-search.php">
9+
<MixedArgument>
10+
<code><![CDATA[$document['name']]]></code>
11+
<code><![CDATA[$index->name]]></code>
12+
</MixedArgument>
13+
<MixedArrayAccess>
14+
<code><![CDATA[$document['name']]]></code>
15+
</MixedArrayAccess>
16+
<MixedAssignment>
17+
<code>$document</code>
18+
<code>$index</code>
19+
<code>$index</code>
20+
<code>$index</code>
21+
</MixedAssignment>
22+
<MixedPropertyFetch>
23+
<code><![CDATA[$index->name]]></code>
24+
<code><![CDATA[$index->name]]></code>
25+
<code><![CDATA[$index->name]]></code>
26+
<code><![CDATA[$index->queryable]]></code>
27+
</MixedPropertyFetch>
28+
</file>
829
<file src="src/ChangeStream.php">
930
<DeprecatedConstant>
1031
<code>self::CURSOR_NOT_FOUND</code>

0 commit comments

Comments
 (0)