Skip to content

Commit d29ab3b

Browse files
committed
PHPLIB-1143: Add search index operations to Collection class
mongodb/specifications@ae35908
1 parent 2f09005 commit d29ab3b

11 files changed

+1125
-2
lines changed

src/Collection.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@
3636
use MongoDB\Operation\Count;
3737
use MongoDB\Operation\CountDocuments;
3838
use MongoDB\Operation\CreateIndexes;
39+
use MongoDB\Operation\CreateSearchIndexes;
3940
use MongoDB\Operation\DeleteMany;
4041
use MongoDB\Operation\DeleteOne;
4142
use MongoDB\Operation\Distinct;
4243
use MongoDB\Operation\DropCollection;
4344
use MongoDB\Operation\DropEncryptedCollection;
4445
use MongoDB\Operation\DropIndexes;
46+
use MongoDB\Operation\DropSearchIndex;
4547
use MongoDB\Operation\EstimatedDocumentCount;
4648
use MongoDB\Operation\Explain;
4749
use MongoDB\Operation\Explainable;
@@ -53,6 +55,7 @@
5355
use MongoDB\Operation\InsertMany;
5456
use MongoDB\Operation\InsertOne;
5557
use MongoDB\Operation\ListIndexes;
58+
use MongoDB\Operation\ListSearchIndexes;
5659
use MongoDB\Operation\MapReduce;
5760
use MongoDB\Operation\RenameCollection;
5861
use MongoDB\Operation\ReplaceOne;
@@ -390,6 +393,50 @@ public function createIndexes(array $indexes, array $options = [])
390393
return $operation->execute($server);
391394
}
392395

396+
/**
397+
* @param string $name
398+
* @param array|object $definition
399+
* @param array $options
400+
* @return string The name of the created search index
401+
*/
402+
public function createSearchIndex(string $name, $definition, array $options = []): string
403+
{
404+
$server = select_server($this->manager, $options);
405+
406+
if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
407+
$options['writeConcern'] = $this->writeConcern;
408+
}
409+
410+
$indexes = [
411+
[
412+
'name' => $name,
413+
'definition' => $definition,
414+
],
415+
];
416+
417+
$operation = new CreateSearchIndexes($this->databaseName, $this->collectionName, $indexes, $options);
418+
419+
return current($operation->execute($server));
420+
}
421+
422+
/**
423+
* @param array $indexes
424+
* @param array $options
425+
* @return string[]
426+
*/
427+
public function createSearchIndexes(array $indexes, array $options = []): array
428+
{
429+
$server = select_server($this->manager, $options);
430+
431+
if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
432+
$options['writeConcern'] = $this->writeConcern;
433+
}
434+
435+
$operation = new CreateSearchIndexes($this->databaseName, $this->collectionName, $indexes, $options);
436+
437+
return $operation->execute($server);
438+
}
439+
393440
/**
394441
* Deletes all documents matching the filter.
395442
*
@@ -567,6 +614,27 @@ public function dropIndexes(array $options = [])
567614
return $operation->execute($server);
568615
}
569616

617+
/**
618+
* Drop a single search index in the collection.
619+
*
620+
* @param string|IndexInfo $indexName Index name or model object
621+
* @param array $options Additional options
622+
* @return array|object Command result document
623+
* @throws UnsupportedException if options are not supported by the selected server
624+
* @throws InvalidArgumentException for parameter/option parsing errors
625+
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
626+
*/
627+
public function dropSearchIndex(string $indexName, array $options = [])
628+
{
629+
$indexName = (string) $indexName;
630+
631+
$server = select_server($this->manager, $options);
632+
633+
$operation = new DropSearchIndex($this->databaseName, $this->collectionName, $indexName);
634+
635+
return $operation->execute($server);
636+
}
637+
570638
/**
571639
* Gets an estimated number of documents in the collection using the collection metadata.
572640
*
@@ -941,6 +1009,22 @@ public function listIndexes(array $options = [])
9411009
return $operation->execute($server);
9421010
}
9431011

1012+
/**
1013+
* Returns information for all indexes for the collection.
1014+
*
1015+
* @see ListSearchIndexes::__construct() for supported aggregation and list options
1016+
* @return IndexInfoIterator
1017+
* @throws InvalidArgumentException for parameter/option parsing errors
1018+
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
1019+
*/
1020+
public function listSearchIndexes(string $name, array $aggregationOptions = [], array $listIndexOptions = [])
1021+
{
1022+
$operation = new ListSearchIndexes($this->databaseName, $this->collectionName, $aggregationOptions, $listIndexOptions);
1023+
$server = select_server($this->manager, $listIndexOptions);
1024+
1025+
return $operation->execute($server);
1026+
}
1027+
9441028
/**
9451029
* Executes a map-reduce aggregation on the collection.
9461030
*

src/Model/SearchIndexInput.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/*
3+
* Copyright 2015-present MongoDB, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace MongoDB\Model;
19+
20+
use MongoDB\BSON\Serializable;
21+
use MongoDB\Exception\InvalidArgumentException;
22+
23+
use function is_array;
24+
use function is_object;
25+
use function is_string;
26+
27+
/**
28+
* Search index input model class.
29+
*
30+
* This class is used to validate user input for search index creation.
31+
*
32+
* @internal
33+
* @see \MongoDB\Collection::createSearchIndexes()
34+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/index-management.rst#search-indexes
35+
* @see https://mongodb.com/docs/manual/reference/method/db.collection.createSearchIndex/
36+
*/
37+
class SearchIndexInput implements Serializable
38+
{
39+
/** @var array */
40+
private $searchIndex;
41+
42+
/**
43+
* @param array $index Index specification
44+
* @throws InvalidArgumentException
45+
*/
46+
public function __construct(array $index)
47+
{
48+
if (! isset($index['name'])) {
49+
throw new InvalidArgumentException('Required "name" string is missing from index specification');
50+
}
51+
52+
if (! is_string($index['name'])) {
53+
throw InvalidArgumentException::invalidType('"name" option', $index['name'], 'string');
54+
}
55+
56+
if (! isset($index['definition'])) {
57+
throw new InvalidArgumentException('Required "definition" document is missing from search index specification');
58+
}
59+
60+
if (! is_array($index['definition']) && ! is_object($index['definition'])) {
61+
throw InvalidArgumentException::invalidType('"definition" option', $index['definition'], 'array or object');
62+
}
63+
64+
$this->searchIndex = $index;
65+
}
66+
67+
/**
68+
* Return the index name.
69+
*/
70+
public function __toString(): string
71+
{
72+
return $this->searchIndex['name'];
73+
}
74+
75+
/**
76+
* Serialize the search index information to BSON for search index creation.
77+
*
78+
* @see \MongoDB\Collection::createSearchIndexes()
79+
* @see https://php.net/mongodb-bson-serializable.bsonserialize
80+
*/
81+
public function bsonSerialize(): array
82+
{
83+
return $this->searchIndex;
84+
}
85+
}

src/Operation/CreateSearchIndexes.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
/*
3+
* Copyright 2015-present MongoDB, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace MongoDB\Operation;
19+
20+
use MongoDB\Driver\Command;
21+
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
22+
use MongoDB\Driver\Server;
23+
use MongoDB\Exception\InvalidArgumentException;
24+
use MongoDB\Exception\UnsupportedException;
25+
use MongoDB\Model\SearchIndexInput;
26+
27+
use function array_is_list;
28+
use function array_map;
29+
use function is_array;
30+
use function sprintf;
31+
32+
/**
33+
* Operation for the createIndexes command.
34+
*
35+
* @see \MongoDB\Collection::createSearchIndex()
36+
* @see \MongoDB\Collection::createSearchIndexes()
37+
* @see https://mongodb.com/docs/manual/reference/command/createSearchIndexes/
38+
*/
39+
class CreateSearchIndexes implements Executable
40+
{
41+
/** @var integer */
42+
private static $wireVersionForCommitQuorum = 9;
43+
44+
/** @var string */
45+
private $databaseName;
46+
47+
/** @var string */
48+
private $collectionName;
49+
50+
/** @var array */
51+
private $indexes = [];
52+
53+
/**
54+
* Constructs a createSearchIndexes command.
55+
*
56+
* @param string $databaseName Database name
57+
* @param string $collectionName Collection name
58+
* @param array[] $indexes List of search index specifications
59+
* @throws InvalidArgumentException for parameter parsing errors
60+
*/
61+
public function __construct(string $databaseName, string $collectionName, array $indexes)
62+
{
63+
if (empty($indexes)) {
64+
throw new InvalidArgumentException('$indexes is empty');
65+
}
66+
67+
if (! array_is_list($indexes)) {
68+
throw new InvalidArgumentException('$indexes is not a list');
69+
}
70+
71+
foreach ($indexes as $i => $index) {
72+
if (! is_array($index)) {
73+
throw InvalidArgumentException::invalidType(sprintf('$index[%d]', $i), $index, 'array');
74+
}
75+
76+
$this->indexes[] = new SearchIndexInput($index);
77+
}
78+
79+
$this->databaseName = $databaseName;
80+
$this->collectionName = $collectionName;
81+
}
82+
83+
/**
84+
* Execute the operation.
85+
*
86+
* @see Executable::execute()
87+
* @return string[] The names of the created indexes
88+
* @throws UnsupportedException if write concern is used and unsupported
89+
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
90+
*/
91+
public function execute(Server $server)
92+
{
93+
$this->executeCommand($server);
94+
95+
return array_map(function (SearchIndexInput $index) {
96+
return (string) $index;
97+
}, $this->indexes);
98+
}
99+
100+
/**
101+
* Create one or more indexes for the collection using the createSearchIndexes command.
102+
*
103+
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
104+
*/
105+
private function executeCommand(Server $server): void
106+
{
107+
$cmd = [
108+
'createSearchIndexes' => $this->collectionName,
109+
'indexes' => $this->indexes,
110+
];
111+
112+
$server->executeWriteCommand($this->databaseName, new Command($cmd));
113+
}
114+
}

src/Operation/DropIndexes.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ class DropIndexes implements Executable
7676
*/
7777
public function __construct(string $databaseName, string $collectionName, string $indexName, array $options = [])
7878
{
79-
$indexName = $indexName;
80-
8179
if ($indexName === '') {
8280
throw new InvalidArgumentException('$indexName cannot be empty');
8381
}

0 commit comments

Comments
 (0)