1
types:
            product:
                mappings:
                    title:    { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                    status:
                    brand.name:    { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                    brand:
                      type: "nested"
                      properties:
                          status: ~
                persistence:
                    driver: orm
                    model: MyBundle\Entity\Product\Product
                    provider: 
                      query_builder_method: customProductQueryBuilderElastica
                    listener: ~ 
                    finder: ~

これは、タイプ product の私のマッピングです。customProductQueryBuilderElasticaには、アクティブなステータスがあり、関連するブランド ステータスがアクティブな製品のみを入力するコードが含まれています。管理者から製品を変更すると、完全に機能します。

私がやりたいことは、ブランドのステータスを非アクティブに変更したときに、関連するすべての製品を ES から削除する必要があることです。

そのために、ここで説明されているように、ブランドを製品のネストとして使用し、そのリスナーを作成しました。これで、ES 内のすべての製品のブランド ステータスを自動的に変更できるようになりましたが、ブランド ステータスが非アクティブに設定されたときにそのような製品を削除したいと考えています。どうすればこれをより良い方法で達成できますか?.

4

1 に答える 1

1

何度も試した後。私はついに私が望むものを達成しました。ここにコードを投稿して、他の人を助けようとしています。

@maercky に感謝します。私はここに与えられた彼の答えを参照しました

これが私のconfig.ymlファイルです。

types:
            product:
                mappings:
                    title:    { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                    status:
                    brand.name:    { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                    brand:
                      type: "nested"
                      properties:
                          status: ~
                persistence:
                    driver: orm
                    model: XXX\MyBundle\Entity\Product\Product
                    provider: 
                      query_builder_method: customProductQueryBuilderElastica
                    listener: ~ 
                    finder: ~

このコードは service.yml に移動します

fos_elastica.listener.brand.product:
    class: 'XXX\MyBundle\Listener\ElasticaBrandListener'
    arguments:
        - @fos_elastica.object_persister.search.product
        - ['postPersist', 'postUpdate', 'postRemove', 'preRemove']
        - @fos_elastica.indexable
    calls:
        - [ setContainer, [ '@service_container', @fos_elastica.object_persister.search.product ] ]
    tags:
        - { name: 'doctrine.event_subscriber' }

そして最後に、これはブランドのリスナーです

    <?php

namespace  XXX\MyBundle\Listener;

use FOS\ElasticaBundle\Doctrine\Listener as BaseListener;
use Doctrine\Common\EventArgs;
use Symfony\Component\DependencyInjection\ContainerInterface;
use XXX\MyBundle\Entity\Supplier\Brand;
use FOS\ElasticaBundle\Persister\ObjectPersister;

class ElasticaBrandListener extends BaseListener
{

    /** @var \Symfony\Component\DependencyInjection\ContainerInterface */
    private $container;
    private $objectPersisterProducts;

    public function setContainer(ContainerInterface $container,ObjectPersister $objectPersisterProduct) {
        $this->container = $container;
        $this->objectPersisterProducts = $objectPersisterProduct;
    }

    /**
     * @param Doctrine\Common\EventArgs $eventArgs
     */
    public function postUpdate(EventArgs $eventArgs)
    {
        /** @var $brand Brand */
        $brand = $eventArgs->getEntity();

        if ($brand instanceof Brand) {
            $this->scheduledForUpdate[] = $brand;
            foreach ($brand->getProducts() as $product) {
                $brand_status = $brand->getStatus();
                $product_status = $product->getStatus();
                if($brand_status == 'active' && $product_status == 'active'){
                    $this->objectPersisterProducts->replaceOne($product);
                }else{
                    $this->objectPersisterProducts->deleteOne($product);
                }

            }
        }
    }
}
?>

これはすべて私にとってうまく機能するので、他の人に貢献しています。

于 2014-09-26T13:16:24.387 に答える