diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php b/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php index 558ab6a860..335add4fe4 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php @@ -1220,9 +1220,15 @@ public function hasIndexes(): bool */ public function addSearchIndex(array $definition, ?string $name = null): void { + $name ??= self::DEFAULT_SEARCH_INDEX_NAME; + + if (empty($definition['mappings']['dynamic']) && empty($definition['mappings']['fields'])) { + throw MappingException::emptySearchIndexDefinition($this->name, $name); + } + $this->searchIndexes[] = [ 'definition' => $definition, - 'name' => $name ?? self::DEFAULT_SEARCH_INDEX_NAME, + 'name' => $name, ]; } diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php b/lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php index af7d22a28f..68438848c1 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php +++ b/lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php @@ -291,4 +291,9 @@ public static function nonBackedEnumMapped(string $className, string $fieldName, $fieldName, )); } + + public static function emptySearchIndexDefinition(string $className, string $indexName): self + { + return new self(sprintf('%s search index "%s" must be dynamic or specify a field mapping', $className, $indexName)); + } } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php index cb905e9acf..cbf6d7fa73 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php @@ -971,6 +971,15 @@ public function testDefaultValueForValidationLevel(): void $cm = new ClassMetadata('stdClass'); self::assertEquals(ClassMetadata::SCHEMA_VALIDATION_LEVEL_STRICT, $cm->getValidationLevel()); } + + public function testEmptySearchIndexDefinition(): void + { + $cm = new ClassMetadata('stdClass'); + + $this->expectException(MappingException::class); + $this->expectExceptionMessage('stdClass search index "default" must be dynamic or specify a field mapping'); + $cm->addSearchIndex(['mappings' => []]); + } } /** @template-extends DocumentRepository */