mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 15:33:15 +00:00
Pass structure to query visitor & enable range generation for regular fields (equal expression)
This commit is contained in:
@@ -24,6 +24,7 @@ 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\QueryContextFactory;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryCompiler;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\GlobalStructure;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
|
||||
@@ -62,7 +63,7 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
|
||||
$app['search_engine.structure'],
|
||||
$app['elasticsearch.client'],
|
||||
$options->getIndexName(),
|
||||
$app['locales.available'],
|
||||
$app['query_context.factory'],
|
||||
$app['elasticsearch.facets_response.factory'],
|
||||
$options
|
||||
);
|
||||
@@ -181,6 +182,14 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
|
||||
);
|
||||
});
|
||||
|
||||
$app['query_context.factory'] = $app->share(function ($app) {
|
||||
return new QueryContextFactory(
|
||||
$app['search_engine.structure'],
|
||||
array_keys($app['locales.available']),
|
||||
$app['locale']
|
||||
);
|
||||
});
|
||||
|
||||
$app['query_parser.grammar_path'] = function ($app) {
|
||||
$configPath = ['registry', 'searchengine', 'query-grammar-path'];
|
||||
$grammarPath = $app['conf']->get($configPath, 'grammar/query.pp');
|
||||
@@ -197,6 +206,7 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
|
||||
$app['query_compiler'] = $app->share(function ($app) {
|
||||
return new QueryCompiler(
|
||||
$app['query_parser'],
|
||||
$app['search_engine.structure'],
|
||||
$app['thesaurus']
|
||||
);
|
||||
});
|
||||
|
@@ -20,6 +20,11 @@ class FieldKey implements Key, QueryPostProcessor
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getIndexField(QueryContext $context, $raw = false)
|
||||
{
|
||||
return $this->getField($context)->getIndexField($raw);
|
||||
|
@@ -19,8 +19,8 @@ use Alchemy\Phrasea\SearchEngine\Elastic\Search\AggregationHelper;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\FacetsResponse;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryCompiler;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContextFactory;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Flag;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\LimitedStructure;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
||||
@@ -48,12 +48,12 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
/** @var ElasticsearchOptions */
|
||||
private $options;
|
||||
|
||||
public function __construct(Application $app, Structure $structure, Client $client, $indexName, array $locales, Closure $facetsResponseFactory, ElasticsearchOptions $options)
|
||||
public function __construct(Application $app, Structure $structure, Client $client, $indexName, QueryContextFactory $context_factory, Closure $facetsResponseFactory, ElasticsearchOptions $options)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->structure = $structure;
|
||||
$this->client = $client;
|
||||
$this->locales = array_keys($locales);
|
||||
$this->context_factory = $context_factory;
|
||||
$this->facetsResponseFactory = $facetsResponseFactory;
|
||||
$this->options = $options;
|
||||
|
||||
@@ -62,6 +62,7 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
}
|
||||
|
||||
$this->indexName = $indexName;
|
||||
|
||||
}
|
||||
|
||||
public function getIndexName()
|
||||
@@ -261,12 +262,7 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
public function query($string, $offset, $perPage, SearchEngineOptions $options = null)
|
||||
{
|
||||
$options = $options ?: new SearchEngineOptions();
|
||||
|
||||
$narrowToFields = array();
|
||||
foreach($options->getFields() as $field) {
|
||||
$narrowToFields[] = $field->get_name();
|
||||
}
|
||||
$context = $this->createQueryContext($options)->narrowToFields($narrowToFields);
|
||||
$context = $this->context_factory->createContext($options);
|
||||
|
||||
/** @var QueryCompiler $query_compiler */
|
||||
$query_compiler = $this->app['query_compiler'];
|
||||
@@ -352,23 +348,6 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Move in search engine service provider
|
||||
*/
|
||||
private function createQueryContext(SearchEngineOptions $options)
|
||||
{
|
||||
return new QueryContext(
|
||||
$this->getLimitedStructure($options),
|
||||
$this->locales,
|
||||
$this->app['locale']
|
||||
);
|
||||
}
|
||||
|
||||
private function getLimitedStructure(SearchEngineOptions $options)
|
||||
{
|
||||
return new LimitedStructure($this->structure, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -455,7 +434,7 @@ class ElasticSearchEngine implements SearchEngineInterface
|
||||
$base_facet_agg['terms']['field'] = 'type';
|
||||
$aggs['Type'] = $base_facet_agg;
|
||||
|
||||
$structure = $this->getLimitedStructure($options);
|
||||
$structure = $this->context_factory->getLimitedStructure($options);
|
||||
foreach ($structure->getFacetFields() as $name => $field) {
|
||||
// 2015-05-26 (mdarse) Removed databox filtering.
|
||||
// It was already done by the ACL filter in the query scope, so no
|
||||
|
@@ -4,6 +4,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Thesaurus;
|
||||
use Hoa\Compiler\Exception\Exception as CompilerException;
|
||||
use Hoa\Compiler\Llk\Parser;
|
||||
@@ -14,6 +15,7 @@ use Hoa\Visitor\Visit;
|
||||
class QueryCompiler
|
||||
{
|
||||
private $parser;
|
||||
private $structure;
|
||||
private $thesaurus;
|
||||
|
||||
private static $leftAssociativeOperators = array(
|
||||
@@ -22,9 +24,10 @@ class QueryCompiler
|
||||
NodeTypes::EXCEPT_EXPR
|
||||
);
|
||||
|
||||
public function __construct(Parser $parser, Thesaurus $thesaurus)
|
||||
public function __construct(Parser $parser, Structure $structure, Thesaurus $thesaurus)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$this->structure = $structure;
|
||||
$this->thesaurus = $thesaurus;
|
||||
}
|
||||
|
||||
@@ -54,7 +57,12 @@ class QueryCompiler
|
||||
*/
|
||||
public function parse($string, $postprocessing = true)
|
||||
{
|
||||
return $this->visitString($string, new QueryVisitor(), $postprocessing);
|
||||
return $this->visitString($string, $this->createQueryVisitor(), $postprocessing);
|
||||
}
|
||||
|
||||
private function createQueryVisitor()
|
||||
{
|
||||
return new QueryVisitor($this->structure);
|
||||
}
|
||||
|
||||
public function dump($string, $postprocessing = true)
|
||||
|
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\LimitedStructure;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
|
||||
|
||||
class QueryContextFactory
|
||||
{
|
||||
private $structure;
|
||||
|
||||
public function __construct(Structure $structure, array $locales, $current_locale)
|
||||
{
|
||||
$this->structure = $structure;
|
||||
$this->locales = $locales;
|
||||
$this->current_locale = $current_locale;
|
||||
}
|
||||
|
||||
public function createContext(SearchEngineOptions $options = null)
|
||||
{
|
||||
$structure = $options
|
||||
? $this->getLimitedStructure($options)
|
||||
: $this->structure;
|
||||
|
||||
$context = new QueryContext($structure, $this->locales, $this->current_locale);
|
||||
|
||||
if ($options) {
|
||||
$fields = $this->getSearchedFields($options);
|
||||
$context = $context->narrowToFields($fields);
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
private function getSearchedFields(SearchEngineOptions $options)
|
||||
{
|
||||
$fields = [];
|
||||
foreach ($options->getFields() as $field) {
|
||||
$fields[] = $field->get_name();
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function getLimitedStructure(SearchEngineOptions $options)
|
||||
{
|
||||
return new LimitedStructure($this->structure, $options);
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\Exception;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryHelper;
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||
use Hoa\Compiler\Llk\TreeNode;
|
||||
use Hoa\Visitor\Element;
|
||||
use Hoa\Visitor\Visit;
|
||||
@@ -12,6 +13,13 @@ use InvalidArgumentException;
|
||||
|
||||
class QueryVisitor implements Visit
|
||||
{
|
||||
private $structure;
|
||||
|
||||
public function __construct(Structure $structure)
|
||||
{
|
||||
$this->structure = $structure;
|
||||
}
|
||||
|
||||
public function visit(Element $element, &$handle = null, $eldnah = null)
|
||||
{
|
||||
if (null !== $value = $element->getValue()) {
|
||||
@@ -197,7 +205,12 @@ class QueryVisitor implements Visit
|
||||
|
||||
private function isDateKey(AST\KeyValue\Key $key)
|
||||
{
|
||||
return $key instanceof AST\KeyValue\TimestampKey;
|
||||
if ($key instanceof AST\KeyValue\TimestampKey) {
|
||||
return true;
|
||||
} elseif ($key instanceof AST\KeyValue\FieldKey) {
|
||||
return $this->structure->get($key->getName()) !== null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function visitTerm(Element $element)
|
||||
|
Reference in New Issue
Block a user