mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 07:23:13 +00:00
Implement private fields on range an equal nodes
New QueryContext::get() method Removed QueryContext::normalizeField(), can be replaced with get() and a call to Field::getIndexField().
This commit is contained in:
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryHelper;
|
||||||
|
|
||||||
class FieldEqualsExpression extends Node
|
class FieldEqualsExpression extends Node
|
||||||
{
|
{
|
||||||
@@ -17,11 +19,15 @@ class FieldEqualsExpression extends Node
|
|||||||
|
|
||||||
public function buildQuery(QueryContext $context)
|
public function buildQuery(QueryContext $context)
|
||||||
{
|
{
|
||||||
$field = $context->normalizeField($this->field->getValue());
|
$structure_field = $context->get($this->field);
|
||||||
$query = array();
|
if (!$structure_field) {
|
||||||
$query['term'][$field] = $this->value;
|
throw new QueryException(sprintf('Field "%s" does not exist', $this->field->getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
$query = [];
|
||||||
|
$query['term'][$structure_field->getIndexField()] = $this->value;
|
||||||
|
|
||||||
|
return QueryHelper::wrapPrivateFieldQuery($structure_field, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTermNodes()
|
public function getTermNodes()
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryHelper;
|
||||||
|
|
||||||
class RangeExpression extends Node
|
class RangeExpression extends Node
|
||||||
{
|
{
|
||||||
@@ -59,11 +61,15 @@ class RangeExpression extends Node
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$field = $context->normalizeField($this->field->getValue());
|
$structure_field = $context->get($this->field);
|
||||||
$query = array();
|
if (!$structure_field) {
|
||||||
$query['range'][$field] = $params;
|
throw new QueryException(sprintf('Field "%s" does not exist', $this->field->getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
$query = [];
|
||||||
|
$query['range'][$structure_field->getIndexField()] = $params;
|
||||||
|
|
||||||
|
return QueryHelper::wrapPrivateFieldQuery($structure_field, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTermNodes()
|
public function getTermNodes()
|
||||||
|
@@ -4,6 +4,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
|||||||
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Field as ASTField;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +92,18 @@ class QueryContext
|
|||||||
return array_values($fields);
|
return array_values($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function get($name)
|
||||||
|
{
|
||||||
|
if ($name instanceof ASTField) {
|
||||||
|
$name = $name->getValue();
|
||||||
|
}
|
||||||
|
$field = $this->structure->get($name);
|
||||||
|
if (!$field) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo Maybe we should put this logic in Field class?
|
* @todo Maybe we should put this logic in Field class?
|
||||||
*/
|
*/
|
||||||
@@ -112,23 +125,6 @@ class QueryContext
|
|||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns normalized name or null
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @return null|string
|
|
||||||
* @deprecated Use getIndexField() on Field instance
|
|
||||||
*/
|
|
||||||
public function normalizeField($name)
|
|
||||||
{
|
|
||||||
$field = $this->structure->get($name);
|
|
||||||
if (!$field) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// TODO Field label dereferencing (we only want names)
|
|
||||||
return $field->getIndexField();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFields()
|
public function getFields()
|
||||||
{
|
{
|
||||||
return $this->fields;
|
return $this->fields;
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
|
||||||
|
|
||||||
class QueryHelper
|
class QueryHelper
|
||||||
{
|
{
|
||||||
private function __construct() {}
|
private function __construct() {}
|
||||||
@@ -28,15 +30,32 @@ class QueryHelper
|
|||||||
foreach ($fields_map as $hash => $fields) {
|
foreach ($fields_map as $hash => $fields) {
|
||||||
// Right to query on a private field is dependant of document collection
|
// Right to query on a private field is dependant of document collection
|
||||||
// Here we make sure we can only match on allowed collections
|
// Here we make sure we can only match on allowed collections
|
||||||
$query = [];
|
$queries[] = self::restrictQueryToCollections(
|
||||||
$query['bool']['must'][0]['terms']['base_id'] = $collections_map[$hash];
|
$matcher_callback->__invoke($fields),
|
||||||
$query['bool']['must'][1] = $matcher_callback->__invoke($fields);
|
$collections_map[$hash]
|
||||||
$queries[] = $query;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $queries;
|
return $queries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function wrapPrivateFieldQuery(Field $field, array $query)
|
||||||
|
{
|
||||||
|
if ($field->isPrivate()) {
|
||||||
|
return self::restrictQueryToCollections($query, $field->getDependantCollections());
|
||||||
|
} else {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function restrictQueryToCollections(array $query, array $collections)
|
||||||
|
{
|
||||||
|
$wrapper = [];
|
||||||
|
$wrapper['bool']['must'][0]['terms']['base_id'] = $collections;
|
||||||
|
$wrapper['bool']['must'][1] = $query;
|
||||||
|
return $wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
private static function hashCollections(array $collections)
|
private static function hashCollections(array $collections)
|
||||||
{
|
{
|
||||||
sort($collections, SORT_REGULAR);
|
sort($collections, SORT_REGULAR);
|
||||||
|
@@ -22,19 +22,6 @@ class QueryContextTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(['some_field'], $narrowed->getFields());
|
$this->assertEquals(['some_field'], $narrowed->getFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFieldNormalization()
|
|
||||||
{
|
|
||||||
$public_field = new Field('foo', Mapping::TYPE_STRING, ['private' => false]);
|
|
||||||
$restricted_field = new Field('bar', Mapping::TYPE_STRING, ['private' => true]);
|
|
||||||
$structure = $this->prophesize(Structure::class);
|
|
||||||
$structure->get('foo')->willReturn($public_field);
|
|
||||||
$structure->get('bar')->willReturn($restricted_field);
|
|
||||||
|
|
||||||
$context = new QueryContext($structure->reveal(), [], 'fr');
|
|
||||||
$this->assertEquals('caption.foo', $context->normalizeField('foo'));
|
|
||||||
$this->assertEquals('private_caption.bar', $context->normalizeField('bar'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetUnrestrictedFields()
|
public function testGetUnrestrictedFields()
|
||||||
{
|
{
|
||||||
$foo_field = new Field('foo', Mapping::TYPE_STRING, ['private' => false]);
|
$foo_field = new Field('foo', Mapping::TYPE_STRING, ['private' => false]);
|
||||||
|
Reference in New Issue
Block a user