diff --git a/src/Query/BoolQuery.php b/src/Query/BoolQuery.php index 924ee6cc..56029bd9 100644 --- a/src/Query/BoolQuery.php +++ b/src/Query/BoolQuery.php @@ -111,7 +111,13 @@ public function toArray() $mustContainer = $this->container[self::MUST]; $query = array_shift($mustContainer); - return [$query->getType() => $query->toArray()]; + if ($query->getType() == 'match') { + $output = [self::MUST => [[$query->getType() => $query->toArray()]]]; + } else { + $output = [$query->getType() => $query->toArray()]; + } + + return $output; } foreach ($this->container as $boolType => $builders) { diff --git a/tests/Query/NestedQueryTest.php b/tests/Query/NestedQueryTest.php index 69583698..acb1ce06 100644 --- a/tests/Query/NestedQueryTest.php +++ b/tests/Query/NestedQueryTest.php @@ -11,10 +11,16 @@ namespace ONGR\ElasticsearchDSL\Tests\Unit\DSL\Query; +use ONGR\ElasticsearchDSL\Query\BoolQuery; +use ONGR\ElasticsearchDSL\Query\MatchQuery; use ONGR\ElasticsearchDSL\Query\NestedQuery; +use ONGR\ElasticsearchDSL\Query\RangeQuery; +use ONGR\ElasticsearchDSL\Query\TermQuery; +use ONGR\ElasticsearchDSL\Search; class NestedQueryTest extends \PHPUnit_Framework_TestCase { + /** * Tests toArray method. */ @@ -31,7 +37,7 @@ public function testToArray() ->willReturn(['testKey' => 'testValue']); $result = [ - 'path' => 'test_path', + 'path' => 'test_path', 'query' => [ 'test_type' => ['testKey' => 'testValue'], ], @@ -57,4 +63,201 @@ public function testParameters() $this->assertTrue(method_exists($nestedQuery, 'hasParameter'), 'Nested query must have hasParameter method'); $this->assertTrue(method_exists($nestedQuery, 'getParameter'), 'Nested query must have getParameter method'); } + + /** + * Tests if Nested Query has 1 MUST boolean conditions + */ + public function testWith1MustBoolean() + { + + // Case 1: With one Bool Query + $matchQuery = new MatchQuery('some.field', 'someValue'); + + $boolQuery = new BoolQuery(); + $boolQuery->add($matchQuery, BoolQuery::MUST); + + $nestedQuery = new NestedQuery('urls', $boolQuery); + + $search = new Search(); + $search->addQuery($nestedQuery); + + $expected = [ + 'query' => [ + 'nested' => [ + 'path' => 'urls', + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'match' => ['some.field' => ['query' => 'someValue']] + ] + ] + ] + ] + ] + ] + ]; + + $this->assertEquals($expected, $search->toArray()); + } + + /** + * Tests if Nested Query has 1 SHOULD boolean condition + */ + public function testWith1ShouldBoolean() + { + + // Case 1: With one Bool Query + $matchQuery = new MatchQuery('some.field', 'someValue'); + + $boolQuery = new BoolQuery(); + $boolQuery->add($matchQuery, BoolQuery::SHOULD); + + $nestedQuery = new NestedQuery('urls', $boolQuery); + + $search = new Search(); + $search->addQuery($nestedQuery); + + $expected = [ + 'query' => [ + 'nested' => [ + 'path' => 'urls', + 'query' => [ + 'bool' => [ + 'should' => [ + [ + 'match' => ['some.field' => ['query' => 'someValue']] + ] + ] + ] + ] + ] + ] + ]; + + $this->assertEquals($expected, $search->toArray()); + } + + /** + * Tests if Nested Query has 2 MUST boolean conditions + */ + public function testWith2MustBoolean() + { + $matchQuery = new MatchQuery('obj1.name', 'blue'); + $rangeQuery = new RangeQuery('obj1.count', ['gt' => 5]); + + $boolQuery = new BoolQuery(); + $boolQuery->add($matchQuery); + $boolQuery->add($rangeQuery); + + $nestedQuery = new NestedQuery('obj1', $boolQuery); + $nestedQuery->addParameter('score_mode', 'avg'); + + $search = new Search(); + $search->addQuery($nestedQuery); + + $expected = [ + 'query' => [ + 'nested' => [ + 'path' => 'obj1', + 'score_mode' => 'avg', + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'match' => ['obj1.name' => ['query' => 'blue']] + ], + [ + 'range' => ['obj1.count' => ['gt' => 5]] + ] + ] + ] + ] + ] + ] + ]; + + $this->assertEquals($expected, $search->toArray()); + } + + /** + * Tests if Nested Query has 2 SHOULD boolean conditions + */ + public function testWith2ShouldBoolean() + { + $matchQuery = new MatchQuery('obj1.name', 'blue'); + $rangeQuery = new RangeQuery('obj1.count', ['gt' => 5]); + + $boolQuery = new BoolQuery(); + $boolQuery->add($matchQuery, BoolQuery::SHOULD); + $boolQuery->add($rangeQuery, BoolQuery::SHOULD); + + $nestedQuery = new NestedQuery('obj1', $boolQuery); + $nestedQuery->addParameter('score_mode', 'avg'); + + $search = new Search(); + $search->addQuery($nestedQuery); + + $expected = [ + 'query' => [ + 'nested' => [ + 'path' => 'obj1', + 'score_mode' => 'avg', + 'query' => [ + 'bool' => [ + 'should' => [ + [ + 'match' => ['obj1.name' => ['query' => 'blue']] + ], + [ + 'range' => ['obj1.count' => ['gt' => 5]] + ] + ] + ] + ] + ] + ] + ]; + + $this->assertEquals($expected, $search->toArray()); + } + + /** + * Tests if Nested Query has a mixed boolean condition + */ + public function testWithMixedBoolean() + { + $matchQuery = new MatchQuery('obj1.name', 'blue'); + $rangeQuery = new RangeQuery('obj1.count', ['gt' => 5]); + $termQuery = new TermQuery('obj1.nickname', 'color'); + + $boolQuery = new BoolQuery(); + $boolQuery->add($matchQuery, BoolQuery::MUST); + $boolQuery->add($rangeQuery, BoolQuery::SHOULD); + $boolQuery->add($termQuery, BoolQuery::MUST_NOT); + + $nestedQuery = new NestedQuery('obj1', $boolQuery); + $nestedQuery->addParameter('score_mode', 'avg'); + + $search = new Search(); + $search->addQuery($nestedQuery); + + $expected = [ + 'query' => [ + 'nested' => [ + 'path' => 'obj1', + 'score_mode' => 'avg', + 'query' => [ + 'bool' => [ + 'must' => [['match' => ['obj1.name' => ['query' => 'blue']]]], + 'must_not' => [['term' => ['obj1.nickname' => 'color']]], + 'should' => [['range' => ['obj1.count' => ['gt' => 5]]]] + ] + ] + ] + ] + ]; + + $this->assertEquals($expected, $search->toArray()); + } }