FriendsOfSymfony / FOSElasticaBundle

Elasticsearch PHP integration for your Symfony project using Elastica.
http://friendsofsymfony.github.io
MIT License
1.25k stars 793 forks source link

Issue using SoftDeletion doctrine extension #183

Closed athieriot closed 10 years ago

athieriot commented 11 years ago

Hi,

We currently use the SoftDeletion extension from Gedmo in a Symfony2 app and start building a Search feature around elasticsearch.

We encounter an issue when using the two Bundle together. With SoftDeletion, object are not really deleted but stay in the database with a deletion date field updated.

But, that way, the object is never removed from the index. And we got an exception when Elastica try to map the index object with the related entity.

What is the better way to handle this?

Thank you.

Aurélien

richardmiller-zz commented 11 years ago

Yes, you can specify a method that says whether the entity should be indexed or not, if this returns false for soft deleted entities they will be removed from the index. See the Checking an entity method for listener section of the readme for details of how to specify it in the config.

athieriot commented 11 years ago

The problem is that the SoftDeletion extension execute his logic during the "onFlush" event. Which is too late for the "is_indexable_callback" method to be affected (This one is called during the postUpdate event right?).

For now, my workaround is to use the "postSoftDelete" event and fire a new "postUpdate" event. But it's quite unsure if there is a lot of listeners.

What do you think?

nurikabe commented 11 years ago

I had the same problem. Ended up manually triggering postRemove from another housecleaning listener that I have:

public function postSoftDelete(LifecycleEventArgs $args)
{
    if ($args->getEntity() instanceof MyEntity) {
        $this->container->get('foq_elastica.listener.index.type')->postRemove($args);
    }
}
smilesrg commented 9 years ago

@richardmiller @merk +1 for adding this to cookbook

smilesrg commented 9 years ago

@nurikabe there is no such service. Even if I put index name instead of .type. BTW you have a type (foq instead of fos)

dbu commented 9 years ago

@smilesrg foq was the old version. you are looking at the rewritten current version of bundle.

smilesrg commented 9 years ago

@dbu thanks! I've used $this->container->get("fos_elastica.object_persister.search.$type")->deleteOne($entity); as a temporary solution.

    public function postSoftDelete(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof InstagramShopPicture) {
            $type = 'picture';
        } else if ($entity instanceof InstagramShop) {
            $type = 'shop';
        } else {
            return;
        }

        $this->container->get("fos_elastica.object_persister.search.$type")->deleteOne($entity);
    }
rvdbogerd commented 6 years ago

For all those people still ending up here: it's very easy to fix, just add a Method to your entity like 'isActive' and add that to your config as a persistence listener:

    indexes:
        mynamespace:
                mymodel:
                    mappings:
                        ...
                    persistence:
                        provider: ~
                        model: My\Model
                        repository: My\Repository
                        listener:
                            is_indexable_callback: "isActive"

Then add a little something like this to your model and your done:

    public function isActive(): bool
    {
        return !$this->deletedAt;
    }