diff --git a/examples/atlas-search.php b/examples/atlas-search.php new file mode 100644 index 000000000..53aeb6f6b --- /dev/null +++ b/examples/atlas-search.php @@ -0,0 +1,135 @@ +selectCollection('sample_airbnb', 'listingsAndReviews'); + +$count = $collection->estimatedDocumentCount(); +if ($count === 0) { + echo 'This example requires the sample_airbnb database with the listingsAndReviews collection.', "\n"; + echo 'Load the sample dataset in your MongoDB Atlas cluster before running this example:', "\n"; + echo ' https://www.mongodb.com/docs/atlas/sample-data/', "\n"; + exit(1); +} + +// Delete the index if it already exists +$indexes = iterator_to_array($collection->listSearchIndexes()); +foreach ($indexes as $index) { + if ($index->name === 'default') { + echo "\nThe index already exists. Dropping it.\n"; + $collection->dropSearchIndex($index->name); + + // Wait for the index to be deleted. + wait(function () use ($collection) { + foreach ($collection->listSearchIndexes() as $index) { + if ($index->name === 'default') { + echo '.'; + + return false; + } + } + + echo "\n"; + + return true; + }); + } +} + +// Create the search index +echo "\nCreating the index.\n"; +$collection->createSearchIndex( + /* The index definition requires a mapping + * See: https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/ */ + ['mappings' => ['dynamic' => true]], + // "default" is the default index name, this config can be omitted. + ['name' => 'default'], +); + +// Wait for the index to be ready. +wait(function () use ($collection) { + foreach ($collection->listSearchIndexes() as $index) { + if ($index->name === 'default') { + echo '.'; + + return $index->queryable; + } + } + + return false; +}); + +// Perform a text search +echo "\n", 'Performing a text search...', "\n"; +$results = $collection->aggregate([ + [ + '$search' => [ + 'index' => 'default', + 'text' => [ + 'query' => 'view beach ocean', + 'path' => ['name'], + ], + ], + ], + ['$project' => ['name' => 1, 'description' => 1]], + ['$limit' => 10], +])->toArray(); + +foreach ($results as $document) { + echo ' -', $document['name'], "\n"; +} + +echo "\n", 'Enjoy MongoDB Atlas Search!', "\n\n"; + +/** + * This function waits until the callback returns true or the timeout is reached. + * + * @param Closure():bool $callback + */ +function wait(Closure $callback): void +{ + $timeout = hrtime()[0] + WAIT_TIMEOUT_SEC; + while (hrtime()[0] < $timeout) { + if ($callback()) { + return; + } + + sleep(5); + } + + throw new RuntimeException('Time out'); +} diff --git a/psalm-baseline.xml b/psalm-baseline.xml index f1db3e9fa..7776336e9 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5,6 +5,27 @@ decrypt($document->encryptedField)]]> + + + + name]]> + + + + + + $document + $index + $index + $index + + + name]]> + name]]> + name]]> + queryable]]> + + self::CURSOR_NOT_FOUND