Smart facet value escaping

This commit is contained in:
Mathieu Darse
2015-03-19 13:38:20 +01:00
parent a6d1a275a9
commit b1a03ae566
3 changed files with 23 additions and 11 deletions

View File

@@ -20,6 +20,8 @@ use Alchemy\Phrasea\SearchEngine\Elastic\IndexerSubscriber;
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
use Alchemy\Phrasea\SearchEngine\Elastic\Search\Escaper;
use Alchemy\Phrasea\SearchEngine\Elastic\Search\FacetsResponse;
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryParser;
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
use Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine;
@@ -67,10 +69,17 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
return new ElasticSearchEngine(
$app,
$app['elasticsearch.client'],
$app['elasticsearch.options']['index']
$app['elasticsearch.options']['index'],
$app['locales.available'],
$app['elasticsearch.record_helper'],
$app['elasticsearch.facets_response.factory']
);
});
$app['elasticsearch.facets_response.factory'] = $app->protect(function (array $response) use ($app) {
return new FacetsResponse(new Excaper(), $response);
});
/* Indexer related services */

View File

@@ -13,6 +13,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic;
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\RecordIndexer;
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer\TermIndexer;
use Alchemy\Phrasea\SearchEngine\Elastic\RecordHelper;
use Alchemy\Phrasea\SearchEngine\Elastic\Search\FacetsResponse;
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
@@ -39,12 +40,13 @@ class ElasticSearchEngine implements SearchEngineInterface
private $locales;
private $recordHelper;
public function __construct(Application $app, Client $client, $indexName)
public function __construct(Application $app, Client $client, $indexName, array $locales, RecordHelper $recordHelper, Closure $facetsResponseFactory)
{
$this->app = $app;
$this->client = $client;
$this->locales = array_keys($app['locales.available']);
$this->recordHelper = $this->app['elasticsearch.record_helper'];
$this->locales = array_keys($locales);
$this->recordHelper = $recordHelper;
$this->facetsResponseFactory = $facetsResponseFactory;
if ('' === trim($indexName)) {
throw new \InvalidArgumentException('The provided index name is invalid.');
@@ -292,7 +294,7 @@ class ElasticSearchEngine implements SearchEngineInterface
$results[] = ElasticsearchRecordHydrator::hydrate($hit['_source'], $n++);
}
$facets = new FacetsResponse($res);
$facets = $this->facetsResponseFactory->__invoke($res);
$query['ast'] = $this->app['query_parser']->parse($string)->dump();
$query['query_main'] = $recordQuery;

View File

@@ -7,10 +7,13 @@ use JsonSerializable;
class FacetsResponse implements JsonSerializable
{
private $escaper;
private $facets = array();
public function __construct(array $response)
public function __construct(Escaper $escaper, array $response)
{
$this->escaper = $escaper;
if (!isset($response['aggregations'])) {
return;
}
@@ -47,12 +50,10 @@ class FacetsResponse implements JsonSerializable
private function buildQuery($name, $value)
{
// Strip double quotes from values to prevent broken queries
$value = str_replace('/"/u', ' ', $value);
// TODO escape value when escaping is supported in query parser
$value = $this->escaper->escapeWord($value);
return ($name === 'Collection') ?
sprintf('collection:"%s"', $value) :
sprintf('"%s" IN %s', $value, $name);
sprintf('collection:%s', $value) :
sprintf('%s IN %s', $value, $name);
}
private function throwAggregationResponseError()