我正在使用FosElasticaBundle(@dev)进行Symfony 2.5.6项目。
在我的项目中,我只需要在弹性搜索中获取请求的总命中数。也就是说,我正在使用正常的请求查询弹性搜索,但通过特殊的"计数"网址:
localhost:9200/_search?search_type=count
注意" search_type = count" URL参数。
以下是示例查询:
{
"query": {
"filtered": {
"query": {
"match_all": []
},
"filter": {
"bool": {
"must": [
{
"terms": {
"media.category.id": [
681
]
}
}
]
}
}
}
},
"sort": {
"published_at": {
"order": "desc"
}
},
"size": 1
}
结果包含正常的JSON响应,但 hits
部分中没有任何文档。从这个回复中我很容易得到总数:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 81,
"max_score": 0,
"hits": [ ]
}
}
好的,hits.total == 81
。
现在,我无法通过FOSElasticaBundle从存储库找到任何解决方案。
我试过了:
$query = (...) // building the Elastica query here
$count = $this->finder->findPaginated(
$query,
array(ES::OPTION_SEARCH_TYPE => ES::OPTION_SEARCH_TYPE_COUNT)
)->getNbResults();
但是我试图加载课程" Pagerfanta"。我不想要Pagerfanta。
然后这个:
$count = $this->finder->createPaginatorAdapter(
$query,
array(ES::OPTION_SEARCH_TYPE => ES::OPTION_SEARCH_TYPE_COUNT)
)->getTotalHits();
但它总会给我0。
如果我可以从存储库访问Elastica Finder服务(我可以从查询搜索中获取ResultSet,并且此ResultSet具有正确的getTotalHits()方法),那将很容易。但来自存储库的服务......你知道。
感谢您的帮助或线索!
答案 0 :(得分:2)
我面临同样的挑战,从repo内部访问可搜索的界面。这就是我最终得到的结果:
创建AcmeBundle\Elastica\ExtendedTransformedFinder
。这只是扩展TransformedFinder
类并使searchable
接口可访问。
<?php
namespace AcmeBundle\Elastica;
use FOS\ElasticaBundle\Finder\TransformedFinder;
class ExtendedTransformedFinder extends TransformedFinder
{
/**
* @return \Elastica\SearchableInterface
*/
public function getSearch()
{
return $this->searchable;
}
}
使捆绑使用我们的新类;在service.yml
:
parameters:
fos_elastica.finder.class: AcmeBundle\Elastica\ExtendedTransformedFinder
然后在回购中使用我们班级的getSearch
方法,做你想做的事情:)
class SomeSearchRepository extends Repository
{
public function search(/* ... */)
{
// create and set your query as you like
$query = Query::create();
// ...
// then run a count query
$count = $this->finder->getSearch()->count($query);
}
}
抬头这适用于3.1.x版本。应该从3.0.x开始。
答案 1 :(得分:1)
好的,所以,我们走了:不可能。
从版本3.1.x-dev(2d8903a)开始,您不能从FOSElasticaBundle获取弹性搜索返回的匹配文档总数,因为此捆绑包不会公开此值。
RawPaginatorAdapter::getTotalHits()
方法包含以下代码:
return $this->query->hasParam('size')
? min($this->totalHits, (integer) $this->query->getParam('size'))
: $this->totalHits;
阻止在没有实际需要任何文档的情况下获取正确的$this->totalHits
。实际上,如果将size设置为0,告诉elasticsearch不返回任何文档,只有元信息RawPaginatorAdapter::getTotalHits()
将返回0。
所以FosElasticaBundle并没有提供一种了解这个总命中数的方法,你只能直接通过Elastica库来实现。当然,在\FOS\ElasticaBundle\Repository
中,Elastica发现者可以在本地使用。您必须提供新服务,进行一些注射,并为您提供服务,而不是FOSElasticaBundle用于存储库......哎哟。
我选择了另一条路径,我分叉https://github.com/FriendsOfSymfony/FOSElasticaBundle并更改了方法代码,如下所示:
/**
* Returns the number of results.
*
* @param boolean $genuineTotal make the function return the `hits.total`
* value of the search result in all cases, instead of limiting it to the
* `size` request parameter.
* @return integer The number of results.
*/
public function getTotalHits($genuineTotal = false)
{
if ( ! isset($this->totalHits)) {
$this->totalHits = $this->searchable->search($this->query)->getTotalHits();
}
return $this->query->hasParam('size') && !$genuineTotal
? min($this->totalHits, (integer) $this->query->getParam('size'))
: $this->totalHits;
}
$genuineTotal
boolean恢复弹性搜索行为,不引入任何BC中断。我也可以将它命名为$ignoreSize
并以相反的方式使用它。
我打开了拉取请求:https://github.com/FriendsOfSymfony/FOSElasticaBundle/pull/748
我们会看到!如果这可以帮助一个人我已经开心了!
答案 2 :(得分:0)
虽然,您可以将索引实例作为服务(fos_elastica.index.INDEX_NAME.TYPE_NAME)获取并请求count()方法。
琼