Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indices from sub classes always get re-created #2561

Open
buffcode opened this issue Oct 27, 2023 · 3 comments
Open

Indices from sub classes always get re-created #2561

buffcode opened this issue Oct 27, 2023 · 3 comments
Labels

Comments

@buffcode
Copy link
Contributor

Bug Report

Q A
BC Break no
Version 2.5.3

Summary

Having an inheritance and defining indices on a subclass (eg. UniqueIndex) will always re-create the subclasses' indices.

Current behavior

Having an inheritance and defining indices on a subclass (eg. UniqueIndex) will result in the subclass indices to be dropped on every run of doctrine:mongodb:schema:update and re-created afterwards.

Notice that the index will exist after the command, so the collection looks okay, but the indices are effectively dropped and recreated.
This is usually not such of a big problem but it put some our our databases down after dropping an index on a 0,5 TB collection and starting to recreate it for multiple hours.

How to reproduce

<?php

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document()
 * @ODM\InheritanceType("SINGLE_COLLECTION")
 * @ODM\DiscriminatorField("metadataType")
 */
abstract class Metadata
{
    /**
     * @ODM\Id()
     */
    protected ?string $id = null;

    public function getId(): ?string
    {
        return $this->id;
    }
}
<?php

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document()
 */
class PreAggregationMetadata extends Metadata
{
    /**
     * @ODM\UniqueIndex()
     * @ODM\Field(type="string")
     */
    private string $cacheKey;
}

For debugging purposes add the following code to \Doctrine\ODM\MongoDB\SchemaManager::updateDocumentIndexes, right before $collection->dropIndex(...):

dump('Dropping index ' . $mongoIndex['name'] . ' on ' . $documentName);

Run:

$ bin/console doctrine:mongodb:schema:update
Dropping index cacheKey on Metadata
Updated indexes for all classes
Updated validation for all classes

Expected behavior

No index drop

$ bin/console doctrine:mongodb:schema:update
Updated indexes for all classes
Updated validation for all classes

Workaround

All indices have to be defined on the root class.

@malarzm
Copy link
Member

malarzm commented Oct 28, 2023

@buffcode thanks for the report! Would the same be true if Metadata was mapped as a ODM\MappedSuperclass instead of ODM\Document? That would be more correct from a configuration's point of view as Metadata can not be a document on its own

@malarzm malarzm added the Bug label Oct 28, 2023
@buffcode
Copy link
Contributor Author

@malarzm The effect seems to be the same. Having the parent being abstract without MappedSuperclass is used to be able to query all subclasses ("A mapped superclass cannot be a document and is not queryable."), while ODM automatically returns the correct type.

Nevertheless, while testing various combinations of abstract and MappedSuperclass I also had following error, resulting in no index at the end, presumably because the order of the index creation is not correct:

<?php

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document()
 * @ODM\InheritanceType("SINGLE_COLLECTION")
 * @ODM\DiscriminatorField("metadataType")
 */
class ClassA
{
    /**
     * @ODM\Id()
     */
    protected ?string $id = null;
}
<?php

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document()
 */
class ClassB extends ClassA
{
    /**
     * @ODM\Index()
     */
    protected ?string $foo = null;
}

Output:

$ console dev:doctrine:mongodb:schema:update -vv 2>&1 | grep 'Class'
07:28:02 INFO      [app] [MongoDB] Creating index on ClassA: foo_1
07:28:02 WARNING   [app] [MongoDB] Dropping index on ClassA: foo_1

Database view:
image


IMHO the index comparison needs to take all subclasses into account and perform the index deletion/creation only once per collection. The subclasses can be skipped, as they have already been processed by the parent.

@malarzm malarzm added this to the 2.5.4 milestone Nov 1, 2023
@malarzm
Copy link
Member

malarzm commented Nov 1, 2023

Thanks for checking! You're right, we'll need to improve how indices are created. Most probably in the same vein as #2392 did. Mind taking a stab at it? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants