Symfony Doctrine2和FOSElasticaBundle之间的同步不是实时的?
我有urlSymfony Doctrine2和FOSElasticaBundle之间的同步不是实时的?,symfony,doctrine-orm,elasticsearch,foselasticabundle,Symfony,Doctrine Orm,elasticsearch,Foselasticabundle,我有url/posts来列出最近10篇活跃的帖子。当我编辑最后一篇文章(这10篇文章中的第1篇)时,更改似乎没有实时同步到elasticsearch 这是我的密码: $post = $this->findPostBy....; /** @var EntityManager $entityManager */ $entityManager = $this->getDoctrine()->getManager(); $post->setSta
/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重新编制索引。有什么想法或解决方案吗?刚刚找到了一个解决方案,也许不是最好的方法,但至少它是有效的:
/** @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:)基于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秒。您可以通过阅读找到一些提示。我不确定它是否能解决您的问题,但仍然值得一读。是因为ElastisSearch不同步索引文档,所以您面临竞争条件吗?在索引上调用refresh会强制它重新编制索引,这可以解释为什么它可以解决问题。强制ElasticSearch刷新不是很好,它每1秒自然发生一次。但是强制每个用户刷新代码将导致更多问题和性能问题,尤其是当用户基数增加/页面点击率增加时。我将研究另一种解决办法。