Skip to content

Commit

Permalink
allow mixing inclusive [] and exclusive {} endpoints in range expression
Browse files Browse the repository at this point in the history
so expressions like “date:[NOW/DAY-1DAY TO NOW/DAY+1DAY}” are possible
http://lucidworks.com/blog/date-math-now-and-filter-queries/
  • Loading branch information
Štefan Peťovský committed Aug 28, 2015
1 parent a4a5596 commit b268f35
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 45 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
}
],
"require": {
"php": ">=5.6.0",
"lstrojny/functional-php": "dev-master",
"internations/solr-utils": "~0.4"
},
Expand Down
6 changes: 6 additions & 0 deletions docs/01-expression-builder-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ TO 2012-12-31T23:59:56]`).
$eb->field('publishedOn', $eb->dateRange(new DateTime('2012-01-01 00:00:00'), new DateTime('2012-12-31 23:59:59')));
```

We can also mix inclusive “[]” and exclusive “{}” endpoints, so expressions like `date:[2015-08-27T15:35:04Z/DAY TO 2015-08-27T15:35:04Z/DAY+1DAY}` are possible (as of Solr 4.0, more information http://lucidworks.com/blog/date-math-now-and-filter-queries/)

```php
$eb->field('date', $eb->dateRange(new DateTime('2015-08-27 15:35:04') . '/DAY', new DateTime('2015-08-27 15:35:04') . '/DAY+1DAY'), true, false);
```

## Grouping

Grouping is a powerful feature of Lucene’s search syntax. Let’s search for a list of product names
Expand Down
21 changes: 14 additions & 7 deletions src/InterNations/Component/Solr/Expression/ExpressionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,13 @@ public function fzz($expr, $similarity = null)
*
* @param string $start
* @param string $end
* @param boolean $inclusive
* @param boolean $inclusiveFrom
* @param boolean $inclusiveTo
* @return ExpressionInterface
*/
public function range($start = null, $end = null, $inclusive = true)
public function range($start = null, $end = null, $inclusiveFrom = true, $inclusiveTo = true)
{
return new RangeExpression($start, $end, $inclusive);
return new RangeExpression($start, $end, $inclusiveFrom, $inclusiveTo);
}

/**
Expand All @@ -156,7 +157,7 @@ public function range($start = null, $end = null, $inclusive = true)
*/
public function btwnRange($start = null, $end = null)
{
return new RangeExpression($start, $end, false);
return new RangeExpression($start, $end, false, false);
}

/**
Expand Down Expand Up @@ -403,12 +404,17 @@ public function date(DateTime $date = null, $timezone = false)
* Create a range between two dates (one side may be unlimited which is indicated by passing null)
*
* @param DateTime $from
* @param boolean $inclusiveFrom
* @param DateTime $to
* @param boolean $inclusive
* @param boolean $inclusiveTo
* @param boolean $timezone
* @return ExpressionInterface|null
*/
public function dateRange(DateTime $from = null, DateTime $to = null, $inclusive = true, $timezone = false)
public function dateRange(DateTime $from = null,
DateTime $to = null,
$inclusiveFrom = true,
$inclusiveTo = true,
$timezone = false)
{
if ($from === null && $to === null) {
return null;
Expand All @@ -417,7 +423,8 @@ public function dateRange(DateTime $from = null, DateTime $to = null, $inclusive
return $this->range(
$this->lit($this->date($from, $timezone)),
$this->lit($this->date($to, $timezone)),
$inclusive
$inclusiveFrom,
$inclusiveTo
);
}

Expand Down
25 changes: 17 additions & 8 deletions src/InterNations/Component/Solr/Expression/RangeExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/**
* Range expression class
*
* Let you specify range queries in the like of field:[<start> TO <end>] or field:{<start> TO <end>}
* Let you specify range queries in the like of field:[<start> TO <end>] or field:{<start> TO <end>} or also mixing inclusive/exclusive:[<start> TO <end>} as of Solr 4.0
*/
class RangeExpression extends Expression
{
Expand All @@ -25,24 +25,33 @@ class RangeExpression extends Expression
protected $end;

/**
* Inclusive or exclusive the range start/end?
* Inclusive or exclusive the range start?
*
* @var boolean
*/
protected $inclusive;
protected $inclusiveFrom;

/**
* Inclusive or exclusive the range end?
*
* @var boolean
*/
protected $inclusiveTo;

/**
* Create new range query object
*
* @param string|integer|Expression $start
* @param string|integer|Expression $end
* @param boolean $inclusive
* @param boolean $inclusiveFrom
* @param boolean $inclusiveTo
*/
public function __construct($start = null, $end = null, $inclusive = true)
public function __construct($start = null, $end = null, $inclusiveFrom = true, $inclusiveTo = true)
{
$this->start = $start;
$this->end = $end;
$this->inclusive = (bool) $inclusive;
$this->inclusiveFrom = (bool) $inclusiveFrom;
$this->inclusiveTo = (bool) $inclusiveTo;
}

/**
Expand All @@ -52,10 +61,10 @@ public function __toString()
{
return sprintf(
'%s%s TO %s%s',
$this->inclusive ? '[' : '{',
$this->inclusiveFrom ? '[' : '{',
$this->cast($this->start),
$this->cast($this->end),
$this->inclusive ? ']' : '}'
$this->inclusiveTo ? ']' : '}'
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,27 +426,30 @@ public static function getDateRangeData()
'Europe/Berlin'
),
array(
'[2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z]',
'{2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z]',
'2010-10-11 02:00:00',
'Europe/Berlin',
'2010-10-22 01:59:59',
'Europe/Berlin',
true
false
),
array(
'[2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z]',
'{2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z}',
'2010-10-11 02:00:00',
'Europe/Berlin',
'2010-10-22 01:59:59',
'Europe/Berlin'
'Europe/Berlin',
false,
false
),
array(
'[2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z]',
'[2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z}',
'2010-10-11 02:00:00',
'Europe/Berlin',
'2010-10-22 01:59:59',
'Europe/Berlin',
true
true,
false
),
array(
'[* TO 2010-10-21T23:59:59Z]',
Expand All @@ -456,18 +459,30 @@ public static function getDateRangeData()
'Europe/Berlin'
),
array(
'[2010-10-11T00:00:00Z TO *]',
'{* TO 2010-10-21T23:59:59Z}',
null,
null,
'2010-10-22 01:59:59',
'Europe/Berlin',
false,
false
),
array(
'{2010-10-11T00:00:00Z TO *]',
'2010-10-11 02:00:00',
'Europe/Berlin',
null,
null
null,
false,
true
),
array(
'{2010-10-11T00:00:00Z TO 2010-10-21T23:59:59Z}',
'2010-10-11 02:00:00',
'Europe/Berlin',
'2010-10-22 01:59:59',
'Europe/Berlin',
false,
false
),
array(
Expand All @@ -478,12 +493,13 @@ public static function getDateRangeData()
null
),
array(
'[2010-10-11T04:00:00Z TO 2010-10-22T03:59:59Z]',
'{2010-10-11T04:00:00Z TO 2010-10-22T03:59:59Z}',
'2010-10-11 02:00:00',
'Europe/Berlin',
'2010-10-22 01:59:59',
'Europe/Berlin',
null,
false,
false,
'null',
'Europe/Moscow',
),
Expand All @@ -494,16 +510,18 @@ public static function getDateRangeData()
'2010-10-22 01:59:59',
'Europe/Berlin',
true,
true,
'null',
'Europe/Moscow',
),
array(
'[2010-10-11T04:00:00Z TO 2010-10-22T03:59:59Z]',
'{2010-10-11T04:00:00Z TO 2010-10-22T03:59:59Z}',
'2010-10-11 02:00:00',
'Europe/Berlin',
'2010-10-22 01:59:59',
'Europe/Berlin',
null,
false,
false,
'null',
'Europe/Moscow',
),
Expand All @@ -514,26 +532,29 @@ public static function getDateRangeData()
'2010-10-22 01:59:59',
'Europe/Berlin',
true,
true,
'null',
'Europe/Moscow',
),
array(
'[* TO 2010-10-22T03:59:59Z]',
'{* TO 2010-10-22T03:59:59Z}',
null,
null,
'2010-10-22 01:59:59',
'Europe/Berlin',
null,
false,
false,
'null',
'Europe/Moscow'
),
array(
'[2010-10-11T04:00:00Z TO *]',
'{2010-10-11T04:00:00Z TO *}',
'2010-10-11 02:00:00',
'Europe/Berlin',
null,
null,
null,
false,
false,
'null',
'Europe/Moscow',
),
Expand All @@ -544,6 +565,7 @@ public static function getDateRangeData()
'2010-10-22 01:59:59',
'Europe/Berlin',
false,
false,
'null',
'Europe/Moscow',
),
Expand All @@ -554,6 +576,7 @@ public static function getDateRangeData()
'2010-10-22 01:59:59',
'Europe/Berlin',
false,
false,
'Europe/Berlin',
'Europe/Moscow',
),
Expand All @@ -567,7 +590,8 @@ public function testDateRange(
$fromTimezone,
$to,
$toTimezone,
$inclusive = null,
$inclusiveFrom = null,
$inclusiveTo = null,
$solrTimezone = 'null',
$defaultTimezone = null
)
Expand All @@ -583,11 +607,13 @@ public function testDateRange(
}

$arguments = array($from, $to);
if ($inclusive !== null) {
$arguments[] = $inclusive;

if ($solrTimezone !== 'null') {
$arguments[] = $solrTimezone;
if ($inclusiveFrom !== null) {
$arguments[] = $inclusiveFrom;
if ($inclusiveTo !== null) {
$arguments[] = $inclusiveTo;
if ($solrTimezone !== 'null') {
$arguments[] = $solrTimezone;
}
}
}

Expand All @@ -598,8 +624,10 @@ public function testDateRange(
public function testRange()
{
$this->assertSame('["A" TO "Z"]', (string) $this->eb->range('A', 'Z'));
$this->assertSame('["A" TO "Z"]', (string) $this->eb->range('A', 'Z', true));
$this->assertSame('{"A" TO "Z"}', (string) $this->eb->range('A', 'Z', false));
$this->assertSame('["A" TO "Z"]', (string) $this->eb->range('A', 'Z', true, true));
$this->assertSame('{"A" TO "Z"}', (string) $this->eb->range('A', 'Z', false, false));
$this->assertSame('{"A" TO "Z"]', (string) $this->eb->range('A', 'Z', false, true));
$this->assertSame('["A" TO "Z"}', (string) $this->eb->range('A', 'Z', true, false));
}

public function testFunc()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,15 @@ public function testProximityExpression()

public function testRangeExpression()
{
$this->assertSame('["foo" TO "bar"]', (string) new RangeExpression('foo', 'bar', true));
$this->assertSame('["foo" TO "bar"]', (string) new RangeExpression('foo', 'bar', true, true));
$this->assertSame('{"foo" TO "bar"}', (string) new RangeExpression('foo', 'bar', false, false));
$this->assertSame('{"foo" TO "bar"]', (string) new RangeExpression('foo', 'bar', false, true));
$this->assertSame('["foo" TO "bar"]', (string) new RangeExpression('foo', 'bar'));
$this->assertSame('["foo" TO "foo bar"]', (string) new RangeExpression('foo', new PhraseExpression('foo bar')));
$this->assertSame('{"foo" TO "foo bar"}', (string) new RangeExpression('foo', new PhraseExpression('foo bar'), null, false));
$this->assertSame(
'{"foo" TO "foo bar?"}',
(string) new RangeExpression('foo', new WildcardExpression('?', new PhraseExpression('foo bar')), false)
(string) new RangeExpression('foo', new WildcardExpression('?', new PhraseExpression('foo bar')), false, false)
);
$this->assertSame('[-1 TO 0]', (string) new RangeExpression(-1, 0));
$this->assertSame('[0 TO 1]', (string) new RangeExpression(0, 1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,14 @@ public function testQueryWithPlaceholder_Boolean()
public function testQueryWithPlaceholder_Expression()
{
$query = new QueryString('field:<ph>');
$query->setPlaceholder('ph', new RangeExpression(0, 100, false));

$query->setPlaceholder('ph', new RangeExpression(0, 100, false, false));
$this->assertSame('field:{0 TO 100}', (string) $query);
$query = new QueryString('field:<ph>');
$query->setPlaceholder('ph', new RangeExpression(0, 100, false, true));
$this->assertSame('field:{0 TO 100]', (string) $query);
$query = new QueryString('field:<ph>');
$query->setPlaceholder('ph', new RangeExpression(0, 100, true, false));
$this->assertSame('field:[0 TO 100}', (string) $query);
}

public function testSetPlaceholders()
Expand Down

0 comments on commit b268f35

Please sign in to comment.