Doctrine2和FOSElasticaBundle之间的同步不是实时的吗?

时间:2014-04-06 09:23:31

标签: symfony doctrine-orm elasticsearch foselasticabundle

我有网址/posts列出最新的10个有效帖子。当我编辑最后一篇文章(这10篇文章中的第1篇)时,更改似乎不会实时同步到elasticsearch。

这是我的代码:

    $post = $this->findPostBy....;

    /** @var EntityManager $entityManager */
    $entityManager = $this->getDoctrine()->getManager();
    $post->setStatus(PostModel::STATUS_DELETED);
    $entityManager->persist($post);
    $entityManager->flush();

    return $this->redirect('/posts'); 

执行上述代码后,我将被重定向到/posts,但最后一篇刚刚编辑过且状态更改为已删除的帖子仍会列为最新的10 活跃帖子(这绝对是错误的)。它只在刷新页面时消失(/posts)。

/posts的代码:

    /** @var TransformedFinder $finder */
    $finder = $this->container->get('fos_elastica.finder.index_name.post');
    $query = new Query();
    $filter = new Term(array('status' => PostModel::STATUS_ACTIVE));
    $query->setFilter($filter);
    $query->addSort(array('tttAt' => array('order' => 'desc')));
    $posts = $finder->find($query);

我的映射:

        types:
            post:
                mappings:
                    title:
                        type: string
                        analyzer: post_analyzer
                    description:
                        type: string
                        analyzer: post_analyzer
                    status:
                        type: integer
                    tttAt :
                        type : date
                    createdAt :
                        type : date
                persistence:
                    driver: orm
                    model: MyBundle\Entity\Post
                    finder: ~
                    provider: ~
                    listener: ~

有人能解释我为什么以及如何解决这个问题?

已更新:如果我使用xdebug在大约1或2秒内延迟重定向,则该帖子将不再列在/posts中。所以我认为没有足够的时间让ElasticSearch重新编制索引。任何想法或解决方案?

2 个答案:

答案 0 :(得分:1)

刚刚找到一个解决方案,也许不是最好的方法,但至少它有效:

    /** @var EntityManager $entityManager */
    $entityManager = $this->getDoctrine()->getManager();
    $post->setStatus(PostModel::STATUS_DELETED);
    $entityManager->persist($post);
    $entityManager->flush();

    /** @var Index $type */
    $type = $this->container->get('fos_elastica.index.index_name');
    $type->refresh();

重定向前刷新索引将执行strick:)

答案 1 :(得分:0)

在Michael Bui的回答基础上,我发现以下片段为我提供最新版本的FOSElasticaBundle:

/** @var EntityManager $entityManager */
$entityManager = $this->getDoctrine()->getManager();
$post->setStatus(PostModel::STATUS_DELETED);
$entityManager->persist($post);
$entityManager->flush();

/** @var \Elastica\Type $type */
$type = $this->container->get('fos_elastica.index.--INDEX--.--TYPE--');
$type->getIndex()->refresh();

对于他的回答发表的评论显然仍然适用:不要将此用于任何经常做的事情。

另一个简单的解决方案是在ElasticSearch中为您的刷新间隔进行休眠,默认情况下设置为1秒。