Skip to content

Commit 0d10e3e

Browse files
alekittoruflin
authored andcommitted
add span_containing, span_not and span_within queries (#1319)
1 parent dbdc321 commit 0d10e3e

File tree

11 files changed

+463
-5
lines changed

11 files changed

+463
-5
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file based on the
99

1010
### Added
1111

12+
- Added `Query\SpanContaining`, `Query\SpanWithin` and `Query\SpanNot` [#1319](https://github.com/ruflin/Elastica/pull/1319)
13+
1214
### Improvements
1315

1416
### Deprecated

lib/Elastica/Query/Builder.php

Whitespace-only changes.

lib/Elastica/Query/SpanContaining.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
namespace Elastica\Query;
3+
4+
/**
5+
* SpanContaining query.
6+
*
7+
* @author Alessandro Chitolina <[email protected]>
8+
*
9+
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-containing-query.html
10+
*/
11+
class SpanContaining extends AbstractSpanQuery
12+
{
13+
/**
14+
* Constructs a SpanContaining query object.
15+
*
16+
* @param AbstractSpanQuery $little OPTIONAL
17+
* @param AbstractSpanQuery $big OPTIONAL
18+
*/
19+
public function __construct(AbstractSpanQuery $little = null, AbstractSpanQuery $big = null)
20+
{
21+
if (null !== $little) {
22+
$this->setLittle($little);
23+
}
24+
25+
if (null !== $big) {
26+
$this->setBig($big);
27+
}
28+
}
29+
30+
/**
31+
* @param AbstractSpanQuery $little
32+
*
33+
* @return $this
34+
*/
35+
public function setLittle(AbstractSpanQuery $little)
36+
{
37+
return $this->setParam('little', $little);
38+
}
39+
40+
/**
41+
* @param AbstractSpanQuery $big
42+
*
43+
* @return $this
44+
*/
45+
public function setBig(AbstractSpanQuery $big)
46+
{
47+
return $this->setParam('big', $big);
48+
}
49+
}

lib/Elastica/Query/SpanNear.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,22 @@ public function __construct($clauses = [], $slop = 1, $inOrder = false)
3737

3838
/**
3939
* @param int $slop
40+
*
41+
* @return $this
4042
*/
4143
public function setSlop($slop)
4244
{
43-
$this->setParam('slop', $slop);
45+
return $this->setParam('slop', $slop);
4446
}
4547

4648
/**
4749
* @param bool $inOrder
50+
*
51+
* @return $this
4852
*/
4953
public function setInOrder($inOrder)
5054
{
51-
$this->setParam('in_order', $inOrder);
55+
return $this->setParam('in_order', $inOrder);
5256
}
5357

5458
/**

lib/Elastica/Query/SpanNot.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
namespace Elastica\Query;
3+
4+
/**
5+
* SpanNot query.
6+
*
7+
* @author Alessandro Chitolina <[email protected]>
8+
*
9+
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-not-query.html
10+
*/
11+
class SpanNot extends AbstractSpanQuery
12+
{
13+
/**
14+
* Constructs a SpanWithin query object.
15+
*
16+
* @param AbstractSpanQuery $include OPTIONAL
17+
* @param AbstractSpanQuery $exclude OPTIONAL
18+
*/
19+
public function __construct(AbstractSpanQuery $include = null, AbstractSpanQuery $exclude = null)
20+
{
21+
if (null !== $include) {
22+
$this->setInclude($include);
23+
}
24+
25+
if (null !== $exclude) {
26+
$this->setExclude($exclude);
27+
}
28+
}
29+
30+
/**
31+
* @param AbstractSpanQuery $include
32+
*
33+
* @return $this
34+
*/
35+
public function setInclude(AbstractSpanQuery $include)
36+
{
37+
return $this->setParam('include', $include);
38+
}
39+
40+
/**
41+
* @param AbstractSpanQuery $exclude
42+
*
43+
* @return $this
44+
*/
45+
public function setExclude(AbstractSpanQuery $exclude)
46+
{
47+
return $this->setParam('exclude', $exclude);
48+
}
49+
}

lib/Elastica/Query/SpanWithin.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
namespace Elastica\Query;
3+
4+
/**
5+
* SpanWithin query.
6+
*
7+
* @author Alessandro Chitolina <[email protected]>
8+
*
9+
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-within-query.html
10+
*/
11+
class SpanWithin extends AbstractSpanQuery
12+
{
13+
/**
14+
* Constructs a SpanWithin query object.
15+
*
16+
* @param AbstractSpanQuery $little OPTIONAL
17+
* @param AbstractSpanQuery $big OPTIONAL
18+
*/
19+
public function __construct(AbstractSpanQuery $little = null, AbstractSpanQuery $big = null)
20+
{
21+
if (null !== $little) {
22+
$this->setLittle($little);
23+
}
24+
25+
if (null !== $big) {
26+
$this->setBig($big);
27+
}
28+
}
29+
30+
/**
31+
* @param AbstractSpanQuery $little
32+
*
33+
* @return $this
34+
*/
35+
public function setLittle(AbstractSpanQuery $little)
36+
{
37+
return $this->setParam('little', $little);
38+
}
39+
40+
/**
41+
* @param AbstractSpanQuery $big
42+
*
43+
* @return $this
44+
*/
45+
public function setBig(AbstractSpanQuery $big)
46+
{
47+
return $this->setParam('big', $big);
48+
}
49+
}

lib/Elastica/QueryBuilder/DSL/Query.php

+41-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace Elastica\QueryBuilder\DSL;
33

44
use Elastica\Exception\NotImplementedException;
5+
use Elastica\Query\AbstractSpanQuery;
56
use Elastica\Query\BoolQuery;
67
use Elastica\Query\Boosting;
78
use Elastica\Query\Common;
@@ -26,11 +27,14 @@
2627
use Elastica\Query\Range;
2728
use Elastica\Query\Regexp;
2829
use Elastica\Query\SimpleQueryString;
30+
use Elastica\Query\SpanContaining;
2931
use Elastica\Query\SpanFirst;
3032
use Elastica\Query\SpanMulti;
3133
use Elastica\Query\SpanNear;
34+
use Elastica\Query\SpanNot;
3235
use Elastica\Query\SpanOr;
3336
use Elastica\Query\SpanTerm;
37+
use Elastica\Query\SpanWithin;
3438
use Elastica\Query\Term;
3539
use Elastica\Query\Terms;
3640
use Elastica\Query\Type;
@@ -401,11 +405,16 @@ public function span_near($clauses = [], $slop = 1, $inOrder = false)
401405
/**
402406
* span not query.
403407
*
408+
* @param AbstractSpanQuery|null $include
409+
* @param AbstractSpanQuery|null $exclude
410+
*
411+
* @return SpanNot
412+
*
404413
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-not-query.html
405414
*/
406-
public function span_not()
415+
public function span_not(AbstractSpanQuery $include = null, AbstractSpanQuery $exclude = null)
407416
{
408-
throw new NotImplementedException();
417+
return new SpanNot($include, $exclude);
409418
}
410419

411420
/**
@@ -436,6 +445,36 @@ public function span_term(array $term = [])
436445
return new SpanTerm($term);
437446
}
438447

448+
/**
449+
* span_containing query.
450+
*
451+
* @param AbstractSpanQuery|null $little
452+
* @param AbstractSpanQuery|null $big
453+
*
454+
* @return SpanContaining
455+
*
456+
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-containing-query.html
457+
*/
458+
public function span_containing(AbstractSpanQuery $little = null, AbstractSpanQuery $big = null)
459+
{
460+
return new SpanContaining($little, $big);
461+
}
462+
463+
/**
464+
* span_within query.
465+
*
466+
* @param AbstractSpanQuery|null $little
467+
* @param AbstractSpanQuery|null $big
468+
*
469+
* @return SpanWithin
470+
*
471+
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-within-query.html
472+
*/
473+
public function span_within(AbstractSpanQuery $little = null, AbstractSpanQuery $big = null)
474+
{
475+
return new SpanWithin($little, $big);
476+
}
477+
439478
/**
440479
* term query.
441480
*
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
namespace Elastica\Test\Query;
3+
4+
use Elastica\Document;
5+
use Elastica\Query\SpanContaining;
6+
use Elastica\Query\SpanNear;
7+
use Elastica\Query\SpanTerm;
8+
use Elastica\Test\Base as BaseTest;
9+
10+
class SpanContainingTest extends BaseTest
11+
{
12+
/**
13+
* @group unit
14+
*/
15+
public function testToArray()
16+
{
17+
$field = 'name';
18+
$spanTermQuery1 = new SpanTerm([$field => 'nicolas']);
19+
$spanTermQuery2 = new SpanTerm([$field => ['value' => 'alekitto', 'boost' => 1.5]]);
20+
$spanTermQuery3 = new SpanTerm([$field => 'foobar']);
21+
$spanNearQuery = new SpanNear([$spanTermQuery1, $spanTermQuery2], 5);
22+
23+
$spanContainingQuery = new SpanContaining($spanTermQuery3, $spanNearQuery);
24+
25+
$expected = [
26+
'span_containing' => [
27+
'big' => [
28+
'span_near' => [
29+
'clauses' => [
30+
[
31+
'span_term' => [
32+
'name' => 'nicolas',
33+
],
34+
],
35+
[
36+
'span_term' => [
37+
'name' => [
38+
'value' => 'alekitto',
39+
'boost' => 1.5,
40+
],
41+
],
42+
],
43+
],
44+
'slop' => 5,
45+
'in_order' => false,
46+
],
47+
],
48+
'little' => [
49+
'span_term' => [
50+
'name' => 'foobar',
51+
],
52+
],
53+
],
54+
];
55+
56+
$this->assertEquals($expected, $spanContainingQuery->toArray());
57+
}
58+
59+
/**
60+
* @group functional
61+
*/
62+
public function testSpanContaining()
63+
{
64+
$field = 'lorem';
65+
$value = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse odio lacus, aliquam nec nulla quis, aliquam eleifend eros.';
66+
67+
$index = $this->_createIndex();
68+
$type = $index->getType('test');
69+
70+
$docHitData = [$field => $value];
71+
$doc = new Document(1, $docHitData);
72+
$type->addDocument($doc);
73+
$index->refresh();
74+
75+
$spanTermQuery1 = new SpanTerm([$field => 'adipiscing']);
76+
$spanTermQuery2 = new SpanTerm([$field => 'lorem']);
77+
$spanNearQuery = new SpanNear([$spanTermQuery1, $spanTermQuery2], 5);
78+
79+
$spanContainingQuery = new SpanContaining(new SpanTerm([$field => 'amet']), $spanNearQuery);
80+
$resultSet = $type->search($spanContainingQuery);
81+
$this->assertEquals(1, $resultSet->count());
82+
83+
$spanContainingQuery = new SpanContaining(new SpanTerm([$field => 'not-matching']), $spanNearQuery);
84+
$resultSet = $type->search($spanContainingQuery);
85+
$this->assertEquals(0, $resultSet->count());
86+
}
87+
}

0 commit comments

Comments
 (0)