Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Support for the analytics component
- Function builder
- Query builder
- Solarium\Component\FacetSet::setMatches()
- Solarium\Component\FacetSet::setExcludeTerms()
- Solarium\Component\Facet\Field::setMatches()
Expand Down
84 changes: 84 additions & 0 deletions docs/queries/query-helper/query-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Query builder
-------------

The query builder is a simple helper class to help writing and maintaining (filter) queries using Solr's query language.
While the query will only accept a single (composite) expression, the addition of filter queries can consist of multiple expressions.

Query example
-------------
```php
<?php

use Solarium\Builder\Select\QueryBuilder;

// ...

$query = $client->createSelect();

$expr = QueryBuilder::expr();
$builder = QueryBuilder::create()
->where($expr->andX(
$expr->eq('foo', 'bar'),
$expr->eq('baz', 'qux')
))
;

$query->setQueryFromQueryBuilder($builder);

// which would be equal to
$query->setQuery('foo:"bar" AND baz:"qux"');
```

Filter Query example
-------------
```php
<?php

use Solarium\Builder\Select\QueryBuilder;

// ...

$query = $client->createSelect();

$expr = QueryBuilder::expr();
$builder = QueryBuilder::create()
->where($expr->eq('foo', 'bar')),
->andWhere($expr->neq('baz', 'qux')
);

$query->addFilterQueriesFromQueryBuilder($builder);

// which would be equal to
$value = 'foo:"bar"';
$query->addFilterQuery(['key' => sha1($value), 'query' => $value]);
$value = '-baz:"qux"';
$query->addFilterQuery(['key' => sha1($value), 'query' => $value]);
```

Complex filter queries
----------------------
While the ``addFilterQueriesFromQueryBuilder`` method only provides in setting the facet query key and actual query, the ``QueryBuilder`` can be used in the construction of more complex facet queries.
If one, for example, need to add a tag to the filter query the following method could be used.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If one, for example, need to add a tag to the filter query the following method could be used.
If one, for example, needs to add a tag to the filter query the following method could be used.

```php
<?php

use Solarium\Builder\Select\QueryBuilder;
use Solarium\Builder\Select\QueryExpressionVisitor;

// ...

$query = $client->createSelect();

$expr = QueryBuilder::expr();
$visitor = new QueryExpressionVisitor();

$builder = QueryBuilder::create()
->where($expr->eq('foo', 'bar'))
);

$query->addFilterQuery([
'key' => 'my-key,
'query' => $visitor->dispatch($builder->getExpression()[0]),
'local_tag' => 'my-tag',
]);
```
2 changes: 0 additions & 2 deletions src/Builder/AbstractExpressionVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
/**
* Expression Visitor.
*
* @codeCoverageIgnore
*
* @author wicliff <[email protected]>
*/
abstract class AbstractExpressionVisitor
Expand Down
7 changes: 5 additions & 2 deletions src/Builder/Comparison.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
/**
* Comparison.
*
* @codeCoverageIgnore
*
* @author wicliff <[email protected]>
*/
class Comparison implements ExpressionInterface
Expand Down Expand Up @@ -80,6 +78,11 @@ class Comparison implements ExpressionInterface
*/
public const MATCH = 'MATCH';

/**
* Empty.
*/
public const EMPTY = 'EMPTY';

/**
* @var string
*/
Expand Down
2 changes: 0 additions & 2 deletions src/Builder/CompositeComparison.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
/**
* Composite Expression.
*
* @codeCoverageIgnore
*
* @author wicliff <[email protected]>
*/
class CompositeComparison implements ExpressionInterface
Expand Down
189 changes: 189 additions & 0 deletions src/Builder/Select/ExpressionBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Solarium package.
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code.
*/

namespace Solarium\Builder\Select;

use Solarium\Builder\Comparison;
use Solarium\Builder\CompositeComparison;

/**
* Expression Builder.
*
* @author wicliff <[email protected]>
*/
class ExpressionBuilder
{
/**
* @param null $x
*
* @throws \Solarium\Exception\RuntimeException
*
* @return \Solarium\Builder\CompositeComparison
*/
public function andX($x = null): CompositeComparison
{
return new CompositeComparison(CompositeComparison::TYPE_AND, \func_get_args());
}
Comment on lines +24 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ... operator makes this typehintable and thus more readable.

Suggested change
/**
* @param null $x
*
* @throws \Solarium\Exception\RuntimeException
*
* @return \Solarium\Builder\CompositeComparison
*/
public function andX($x = null): CompositeComparison
{
return new CompositeComparison(CompositeComparison::TYPE_AND, \func_get_args());
}
/**
* @param Comparison ...$comparison
*
* @throws \Solarium\Exception\RuntimeException
*
* @return \Solarium\Builder\CompositeComparison
*/
public function andX(Comparison ...$comparison): CompositeComparison
{
return new CompositeComparison(CompositeComparison::TYPE_AND, $comparison);
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've been working quite a bit with the FunctionBuilder recently and one of the benefits of not typehinting the arguments is that you can pass a string as argument for the edge cases you run into.

for instance creating this function filter(mult(price,quantity),or(cats:equal(category,_))) would translate into

$expression = FunctionBuilder::create()
            ->where($expr->filter($expr->mult('price', 'quantity'), $expr->or('cats:equal(category,_)')))
        ;

as $expr->equals would render a different expression, it cannot be used to generate the desired result.

as this is a helper class, i'd personally prefer to make it not too strict; what do you think?


/**
* @param null $x
*
* @throws \Solarium\Exception\RuntimeException
*
* @return \Solarium\Builder\CompositeComparison
*/
public function orX($x = null): CompositeComparison
{
return new CompositeComparison(CompositeComparison::TYPE_OR, \func_get_args());
}
Comment on lines +36 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* @param null $x
*
* @throws \Solarium\Exception\RuntimeException
*
* @return \Solarium\Builder\CompositeComparison
*/
public function orX($x = null): CompositeComparison
{
return new CompositeComparison(CompositeComparison::TYPE_OR, \func_get_args());
}
/**
* @param Comparison ...$comparison
*
* @throws \Solarium\Exception\RuntimeException
*
* @return \Solarium\Builder\CompositeComparison
*/
public function orX(Comparison ...$comparison): CompositeComparison
{
return new CompositeComparison(CompositeComparison::TYPE_OR, $comparison);
}


/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function eq(string $field, $value): Comparison
{
return new Comparison($field, Comparison::EQ, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function neq(string $field, $value): Comparison
{
return new Comparison($field, Comparison::NEQ, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function lt(string $field, $value): Comparison
{
return new Comparison($field, Comparison::LT, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function gt(string $field, $value): Comparison
{
return new Comparison($field, Comparison::GT, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function lte(string $field, $value): Comparison
{
return new Comparison($field, Comparison::LTE, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function gte(string $field, $value): Comparison
{
return new Comparison($field, Comparison::GTE, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function in(string $field, $value): Comparison
{
return new Comparison($field, Comparison::IN, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function notIn(string $field, $value): Comparison
{
return new Comparison($field, Comparison::NIN, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function range(string $field, $value): Comparison
{
return new Comparison($field, Comparison::RANGE, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function regexp(string $field, $value): Comparison
{
return new Comparison($field, Comparison::REGEXP, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function like(string $field, $value): Comparison
{
return new Comparison($field, Comparison::LIKE, $value);
}

/**
* @param string $field
* @param mixed $value
*
* @return \Solarium\Builder\Comparison
*/
public function match(string $field, $value): Comparison
{
return new Comparison($field, Comparison::MATCH, $value);
}

/**
* @param string $field
*
* @return \Solarium\Builder\Comparison
*/
public function empty(string $field): Comparison
{
return new Comparison($field, Comparison::EMPTY, null);
}
}
Loading