mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Handle equality test on metadata
Still need some work on testing side
This commit is contained in:
@@ -73,11 +73,11 @@ key_value_pair:
|
|||||||
| ::flag_prefix:: flag() ::colon:: ::space::? boolean() #flag_statement
|
| ::flag_prefix:: flag() ::colon:: ::space::? boolean() #flag_statement
|
||||||
| ::field_prefix:: field() ::colon:: ::space::? term() #field_statement
|
| ::field_prefix:: field() ::colon:: ::space::? term() #field_statement
|
||||||
| field() ::colon:: ::space::? term() #field_statement
|
| field() ::colon:: ::space::? term() #field_statement
|
||||||
| key() ::space::? ::lt:: ::space::? value() #less_than
|
| key() ::space::? ::lt:: ::space::? value() #less_than
|
||||||
| key() ::space::? ::gt:: ::space::? value() #greater_than
|
| key() ::space::? ::gt:: ::space::? value() #greater_than
|
||||||
| key() ::space::? ::lte:: ::space::? value() #less_than_or_equal_to
|
| key() ::space::? ::lte:: ::space::? value() #less_than_or_equal_to
|
||||||
| key() ::space::? ::gte:: ::space::? value() #greater_than_or_equal_to
|
| key() ::space::? ::gte:: ::space::? value() #greater_than_or_equal_to
|
||||||
| field() ::space::? ::equal:: ::space::? value() #equal_to
|
| key() ::space::? ::equal:: ::space::? value() #equal_to
|
||||||
|
|
||||||
#native_key:
|
#native_key:
|
||||||
<database>
|
<database>
|
||||||
|
@@ -2,38 +2,41 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue\FieldKey;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue\Key;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\QueryException;
|
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;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryHelper;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryPostProcessor;
|
||||||
|
|
||||||
class FieldEqualsExpression extends Node
|
class FieldEqualsExpression extends Node
|
||||||
{
|
{
|
||||||
private $field;
|
private $key;
|
||||||
private $value;
|
private $value;
|
||||||
|
|
||||||
public function __construct(Field $field, $value)
|
public function __construct(Key $key, $value)
|
||||||
{
|
{
|
||||||
$this->field = $field;
|
$this->key = $key;
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildQuery(QueryContext $context)
|
public function buildQuery(QueryContext $context)
|
||||||
{
|
{
|
||||||
$structure_field = $context->get($this->field);
|
if (!$this->key->isValueCompatible($this->value, $context)) {
|
||||||
if (!$structure_field) {
|
|
||||||
throw new QueryException(sprintf('Field "%s" does not exist', $this->field->getValue()));
|
|
||||||
}
|
|
||||||
if (!$structure_field->isValueCompatible($this->value)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
'term' => [
|
'term' => [
|
||||||
$structure_field->getIndexField(true) => $this->value
|
$this->key->getIndexField($context, true) => $this->value
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
return QueryHelper::wrapPrivateFieldQuery($structure_field, $query);
|
if ($this->key instanceof QueryPostProcessor) {
|
||||||
|
return $this->key->postProcessQuery($query, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTermNodes()
|
public function getTermNodes()
|
||||||
@@ -43,6 +46,6 @@ class FieldEqualsExpression extends Node
|
|||||||
|
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return sprintf('(%s == <value:"%s">)', $this->field, $this->value);
|
return sprintf('(<%s> == <value:"%s">)', $this->key, $this->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,9 +19,9 @@ class FieldKey implements Key, QueryPostProcessor
|
|||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIndexField(QueryContext $context, ...$other)
|
public function getIndexField(QueryContext $context, $raw = false)
|
||||||
{
|
{
|
||||||
return $this->getField($context)->getIndexField(...$other);
|
return $this->getField($context)->getIndexField($raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isValueCompatible($value, QueryContext $context)
|
public function isValueCompatible($value, QueryContext $context)
|
||||||
@@ -41,7 +41,8 @@ class FieldKey implements Key, QueryPostProcessor
|
|||||||
if (!isset($this->field_cache[$hash])) {
|
if (!isset($this->field_cache[$hash])) {
|
||||||
$this->field_cache[$hash] = $context->get($this->name);
|
$this->field_cache[$hash] = $context->get($this->name);
|
||||||
}
|
}
|
||||||
if ($field = $this->field_cache[$hash] === null) {
|
$field = $this->field_cache[$hash];
|
||||||
|
if ($field === null) {
|
||||||
throw new QueryException(sprintf('Field "%s" does not exist', $this->name));
|
throw new QueryException(sprintf('Field "%s" does not exist', $this->name));
|
||||||
}
|
}
|
||||||
return $field;
|
return $field;
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Alchemy\Tests\Phrasea\SearchEngine\AST;
|
namespace Alchemy\Tests\Phrasea\SearchEngine\AST;
|
||||||
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\Field as ASTField;
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST\FieldEqualsExpression;
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST\FieldEqualsExpression;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue\Key;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field as StructureField;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field as StructureField;
|
||||||
|
|
||||||
@@ -17,10 +17,10 @@ class FieldEqualsExpressionTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function testSerialization()
|
public function testSerialization()
|
||||||
{
|
{
|
||||||
$this->assertTrue(method_exists(FieldEqualsExpression::class, '__toString'), 'Class does not have method __toString');
|
$this->assertTrue(method_exists(FieldEqualsExpression::class, '__toString'), 'Class does not have method __toString');
|
||||||
$field = $this->prophesize(ASTField::class);
|
$key = $this->prophesize(Key::class);
|
||||||
$field->__toString()->willReturn('foo');
|
$key->__toString()->willReturn('foo');
|
||||||
$node = new FieldEqualsExpression($field->reveal(), 'bar');
|
$node = new FieldEqualsExpression($key->reveal(), 'bar');
|
||||||
$this->assertEquals('(foo == <value:"bar">)', (string) $node);
|
$this->assertEquals('(<foo> == <value:"bar">)', (string) $node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,20 +28,15 @@ class FieldEqualsExpressionTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
public function testQueryBuild($index_field, $value, $compatible_value, $private, $expected_json)
|
public function testQueryBuild($index_field, $value, $compatible_value, $private, $expected_json)
|
||||||
{
|
{
|
||||||
$structure_field = $this->prophesize(StructureField::class);
|
$query_context = $this->prophesize(QueryContext::class)->reveal();
|
||||||
$structure_field->isValueCompatible($value)->willReturn($compatible_value);
|
|
||||||
$structure_field->getIndexField(true)->willReturn($index_field);
|
|
||||||
$structure_field->isPrivate()->willReturn($private);
|
|
||||||
if ($private) {
|
|
||||||
$structure_field->getDependantCollections()->willReturn(['baz', 'qux']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$ast_field = $this->prophesize(ASTField::class);
|
$key = $this->prophesize(Key::class);
|
||||||
$query_context = $this->prophesize(QueryContext::class);
|
$key->isValueCompatible($value, $query_context)->willReturn($compatible_value);
|
||||||
$query_context->get($ast_field->reveal())->willReturn($structure_field);
|
$key->getIndexField($query_context, true)->willReturn($index_field);
|
||||||
|
// TODO Test keys implementing QueryPostProcessor
|
||||||
|
|
||||||
$node = new FieldEqualsExpression($ast_field->reveal(), 'bar');
|
$node = new FieldEqualsExpression($key->reveal(), 'bar');
|
||||||
$query = $node->buildQuery($query_context->reveal());
|
$query = $node->buildQuery($query_context);
|
||||||
|
|
||||||
$this->assertEquals(json_decode($expected_json, true), $query);
|
$this->assertEquals(json_decode($expected_json, true), $query);
|
||||||
}
|
}
|
||||||
@@ -49,14 +44,15 @@ class FieldEqualsExpressionTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function queryProvider()
|
public function queryProvider()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
['foo.raw', 'bar', true, true, '{
|
// TODO Put this case in another test case
|
||||||
"filtered": {
|
// ['foo.raw', 'bar', true, true, '{
|
||||||
"filter": {
|
// "filtered": {
|
||||||
"terms": {
|
// "filter": {
|
||||||
"base_id": ["baz","qux"] } },
|
// "terms": {
|
||||||
"query": {
|
// "base_id": ["baz","qux"] } },
|
||||||
"term": {
|
// "query": {
|
||||||
"foo.raw": "bar" } } } }'],
|
// "term": {
|
||||||
|
// "foo.raw": "bar" } } } }'],
|
||||||
['foo.raw', 'bar', true, false, '{
|
['foo.raw', 'bar', true, false, '{
|
||||||
"term": {
|
"term": {
|
||||||
"foo.raw": "bar" } }'],
|
"foo.raw": "bar" } }'],
|
||||||
|
@@ -61,9 +61,9 @@ foo < "2015/01/01"|<range:field.foo lt="2015/01/01">
|
|||||||
foo ≤ "2015/01/01"|<range:field.foo lte="2015/01/01">
|
foo ≤ "2015/01/01"|<range:field.foo lte="2015/01/01">
|
||||||
foo > "2015/01/01"|<range:field.foo gt="2015/01/01">
|
foo > "2015/01/01"|<range:field.foo gt="2015/01/01">
|
||||||
foo ≥ "2015/01/01"|<range:field.foo gte="2015/01/01">
|
foo ≥ "2015/01/01"|<range:field.foo gte="2015/01/01">
|
||||||
foo = 42|(<field:foo> == <value:"42">)
|
foo = 42|(<field.foo> == <value:"42">)
|
||||||
foo = bar|(<field:foo> == <value:"bar">)
|
foo = bar|(<field.foo> == <value:"bar">)
|
||||||
foo = "bar"|(<field:foo> == <value:"bar">)
|
foo = "bar"|(<field.foo> == <value:"bar">)
|
||||||
|
|
||||||
# Field narrowing
|
# Field narrowing
|
||||||
foo:bar|(<field:foo> MATCHES <text:"bar">)
|
foo:bar|(<field:foo> MATCHES <text:"bar">)
|
||||||
@@ -109,6 +109,7 @@ meta.Duration < 300|<range:metadata.Duration lt="300">
|
|||||||
meta.Duration ≤ 300|<range:metadata.Duration lte="300">
|
meta.Duration ≤ 300|<range:metadata.Duration lte="300">
|
||||||
meta.Duration > 300|<range:metadata.Duration gt="300">
|
meta.Duration > 300|<range:metadata.Duration gt="300">
|
||||||
meta.Duration ≥ 300|<range:metadata.Duration gte="300">
|
meta.Duration ≥ 300|<range:metadata.Duration gte="300">
|
||||||
|
meta.Duration = 300|(<metadata.Duration> == <value:"300">)
|
||||||
|
|
||||||
# Unescaped "." issue on key prefixes
|
# Unescaped "." issue on key prefixes
|
||||||
fieldOne:foo|(<field:fieldOne> MATCHES <text:"foo">)
|
fieldOne:foo|(<field:fieldOne> MATCHES <text:"foo">)
|
||||||
|
Can't render this file because it contains an unexpected character in line 1 and column 11.
|
Reference in New Issue
Block a user