From bd744e6a67f342975fac67e9c8308ec1716d1400 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Fri, 14 Sep 2018 16:50:59 +0100 Subject: [PATCH 1/5] PERL-970 Allow BSON::Doc as sort argument --- lib/MongoDB/Collection.pm | 3 ++ t/sort-bson-doc.t | 70 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 t/sort-bson-doc.t diff --git a/lib/MongoDB/Collection.pm b/lib/MongoDB/Collection.pm index 5b2d9169..c03cc395 100644 --- a/lib/MongoDB/Collection.pm +++ b/lib/MongoDB/Collection.pm @@ -1857,6 +1857,9 @@ sub __ixhash { elsif ( $type eq 'ARRAY' ) { $hash->{$key} = Tie::IxHash->new( @$ref ); } + elsif ( $ref->$_can('_as_tied_hash') ) { + $hash->{$key} = $ref->_as_tied_hash; + } else { MongoDB::UsageError->throw("Can't convert $type to a Tie::IxHash"); } diff --git a/t/sort-bson-doc.t b/t/sort-bson-doc.t new file mode 100644 index 00000000..3dd49a4f --- /dev/null +++ b/t/sort-bson-doc.t @@ -0,0 +1,70 @@ +# Copyright 2015 - present MongoDB, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; +use Test::More 0.96; +use Test::Fatal; +use Test::Deep qw/!blessed/; + +use utf8; +use Tie::IxHash; + +use MongoDB; +use MongoDB::Error; +use BSON::Types ':all'; + +use lib "t/lib"; +use MongoDBTest qw/skip_unless_mongod build_client get_test_db server_version server_type get_capped/; + +skip_unless_mongod(); + +my $conn = build_client(); +my $testdb = get_test_db($conn); +my $server_version = server_version($conn); +my $server_type = server_type($conn); +my $coll = $testdb->get_collection('test_collection'); + +$coll->insert_many( [ + { _id => 1, size => 10 }, + { _id => 2, size => 5 }, + { _id => 3, size => 15 }, +] ); + +subtest "sort standard hash" => sub { + my @res = $coll->find( {}, { sort => { size => 1 } } )->result->all; + + cmp_deeply \@res, + [ + { _id => 2, size => 5 }, + { _id => 1, size => 10 }, + { _id => 3, size => 15 }, + ], + 'Got correct sort order'; +}; + +subtest "sort BSON::Doc" => sub { + my $b_doc = bson_doc( size => 1 ); + my @res = $coll->find( {}, { sort => $b_doc } )->result->all; + + cmp_deeply \@res, + [ + { _id => 2, size => 5 }, + { _id => 1, size => 10 }, + { _id => 3, size => 15 }, + ], + 'Got correct sort order'; +}; + +done_testing; From b1ab555c04ecea5e02d60b8ff24b01632ac9a527 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 17 Sep 2018 16:57:20 +0100 Subject: [PATCH 2/5] PERL-970 Inline _as_tied_hash conversion for BSON::Doc Also move tests for sorting by BSON::Doc into collection.t --- lib/MongoDB/Collection.pm | 5 +-- t/collection.t | 43 ++++++++++++++++++++++++ t/sort-bson-doc.t | 70 --------------------------------------- 3 files changed, 44 insertions(+), 74 deletions(-) delete mode 100644 t/sort-bson-doc.t diff --git a/lib/MongoDB/Collection.pm b/lib/MongoDB/Collection.pm index c03cc395..7d805b37 100644 --- a/lib/MongoDB/Collection.pm +++ b/lib/MongoDB/Collection.pm @@ -1854,12 +1854,9 @@ sub __ixhash { if ( $type eq 'HASH' ) { $hash->{$key} = Tie::IxHash->new( %$ref ); } - elsif ( $type eq 'ARRAY' ) { + elsif ( $type eq 'ARRAY' || $type eq 'BSON::Doc' ) { $hash->{$key} = Tie::IxHash->new( @$ref ); } - elsif ( $ref->$_can('_as_tied_hash') ) { - $hash->{$key} = $ref->_as_tied_hash; - } else { MongoDB::UsageError->throw("Can't convert $type to a Tie::IxHash"); } diff --git a/t/collection.t b/t/collection.t index ddf3ce56..46dfbf03 100644 --- a/t/collection.t +++ b/t/collection.t @@ -1016,4 +1016,47 @@ for my $criteria ( $js_str, $js_obj ) { }; } +subtest "sort standard hash" => sub { + + $coll->drop; + + $coll->insert_many( [ + { _id => 1, size => 10 }, + { _id => 2, size => 5 }, + { _id => 3, size => 15 }, + ] ); + + my @res = $coll->find( {}, { sort => { size => 1 } } )->result->all; + + cmp_deeply \@res, + [ + { _id => 2, size => 5 }, + { _id => 1, size => 10 }, + { _id => 3, size => 15 }, + ], + 'Got correct sort order'; +}; + +subtest "sort BSON::Doc" => sub { + + $coll->drop; + + $coll->insert_many( [ + { _id => 1, size => 10 }, + { _id => 2, size => 5 }, + { _id => 3, size => 15 }, + ] ); + + my $b_doc = bson_doc( size => 1 ); + my @res = $coll->find( {}, { sort => $b_doc } )->result->all; + + cmp_deeply \@res, + [ + { _id => 2, size => 5 }, + { _id => 1, size => 10 }, + { _id => 3, size => 15 }, + ], + 'Got correct sort order'; +}; + done_testing; diff --git a/t/sort-bson-doc.t b/t/sort-bson-doc.t deleted file mode 100644 index 3dd49a4f..00000000 --- a/t/sort-bson-doc.t +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2015 - present MongoDB, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -use strict; -use warnings; -use Test::More 0.96; -use Test::Fatal; -use Test::Deep qw/!blessed/; - -use utf8; -use Tie::IxHash; - -use MongoDB; -use MongoDB::Error; -use BSON::Types ':all'; - -use lib "t/lib"; -use MongoDBTest qw/skip_unless_mongod build_client get_test_db server_version server_type get_capped/; - -skip_unless_mongod(); - -my $conn = build_client(); -my $testdb = get_test_db($conn); -my $server_version = server_version($conn); -my $server_type = server_type($conn); -my $coll = $testdb->get_collection('test_collection'); - -$coll->insert_many( [ - { _id => 1, size => 10 }, - { _id => 2, size => 5 }, - { _id => 3, size => 15 }, -] ); - -subtest "sort standard hash" => sub { - my @res = $coll->find( {}, { sort => { size => 1 } } )->result->all; - - cmp_deeply \@res, - [ - { _id => 2, size => 5 }, - { _id => 1, size => 10 }, - { _id => 3, size => 15 }, - ], - 'Got correct sort order'; -}; - -subtest "sort BSON::Doc" => sub { - my $b_doc = bson_doc( size => 1 ); - my @res = $coll->find( {}, { sort => $b_doc } )->result->all; - - cmp_deeply \@res, - [ - { _id => 2, size => 5 }, - { _id => 1, size => 10 }, - { _id => 3, size => 15 }, - ], - 'Got correct sort order'; -}; - -done_testing; From 6ed37aec9a0975e8bbec86bfdeb10318858bd962 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Fri, 14 Sep 2018 19:31:53 +0100 Subject: [PATCH 3/5] PERL-927 Coerce hint to IxHash or BSON::Doc if not string --- lib/MongoDB/Collection.pm | 3 + t/hint-coerce.t | 180 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 t/hint-coerce.t diff --git a/lib/MongoDB/Collection.pm b/lib/MongoDB/Collection.pm index 7d805b37..8910aa69 100644 --- a/lib/MongoDB/Collection.pm +++ b/lib/MongoDB/Collection.pm @@ -1209,6 +1209,9 @@ sub aggregate { $options->{maxTimeMS} = $self->max_time_ms; } + # string is OK so we check ref, not just exists + __ixhash( $options, 'hint' ) if ref $options->{hint}; + # read preferences are ignored if the last stage is $out my ($last_op) = keys %{ $pipeline->[-1] }; diff --git a/t/hint-coerce.t b/t/hint-coerce.t new file mode 100644 index 00000000..8676eea2 --- /dev/null +++ b/t/hint-coerce.t @@ -0,0 +1,180 @@ +# Copyright 2015 - present MongoDB, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; +use Test::More 0.96; +use Test::Fatal; +use Test::Deep qw/!blessed/; + +use utf8; +use Tie::IxHash; + +use MongoDB; +use MongoDB::Error; +use BSON::Types ':all'; + +use lib "t/lib"; +use MongoDBTest qw/skip_unless_mongod build_client get_test_db server_version server_type get_capped/; + +skip_unless_mongod(); + +my $conn = build_client(); +my $testdb = get_test_db($conn); +my $server_version = server_version($conn); +my $server_type = server_type($conn); +my $coll = $testdb->get_collection('test_collection'); + +plan skip_all => "hints unsupported on MongoDB $server_version" + unless $server_version >= v3.6.0; + +$coll->insert_many( [ + { _id => 1, category => "cake", type => "chocolate", qty => 10 }, + { _id => 2, category => "cake", type => "ice cream", qty => 25 }, + { _id => 3, category => "pie", type => "boston cream", qty => 20 }, + { _id => 4, category => "pie", type => "blueberry", qty => 15 }, +] ); + +$coll->indexes->create_one( [ qty => 1, type => 1 ] ); +my $index_name = $coll->indexes->create_one( [qty => 1, category => 1 ] ); + +subtest "no hint" => sub { + test_hints(); +}; + +subtest "hint string" => sub { + test_hints( $index_name ); +}; + +subtest "hint array" => sub { + test_hints( [ qty => 1, category => 1 ] ); +}; + +subtest "hint IxHash" => sub { + test_hints( Tie::IxHash->new( qty => 1, category => 1 ) ); +}; + +subtest "hint BSON::Doc" => sub { + test_hints( bson_doc( qty => 1, category => 1 ) ); +}; + +sub test_hints { + my $hint = shift; + test_aggregate( $hint ); + test_count_documents( $hint ); + test_find( $hint ); + test_cursor( $hint ); +} + +sub test_aggregate { + my $hint = shift; + + subtest 'aggregate' => sub { + my $cursor = $coll->aggregate( + [ + { '$sort' => { qty => 1 } }, + { '$match' => { category => 'cake', qty => 10 } }, + { '$sort' => { type => -1 } } ], + { ( defined $hint ? ( hint => $hint ) : () ), explain => 1 } + ); + + my $result = $cursor->next; + + is( ref( $result ), 'HASH', "aggregate with explain returns a hashref" ); + + if ( defined $hint ) { + ok( + scalar( @{ $result->{stages}->[0]->{'$cursor'}->{queryPlanner}->{rejectedPlans} } ) == 0, + "aggregate with hint had no rejectedPlans", + ); + } else { + ok( + scalar( @{ $result->{stages}->[0]->{'$cursor'}->{queryPlanner}->{rejectedPlans} } ) > 0, + "aggregate with no hint had rejectedPlans", + ); + } + }; +} + +sub test_count_documents { + my $hint = shift; + + subtest 'count_document' => sub { + is( + $coll->count_documents( + { category => 'cake', qty => { '$gt' => 0 } }, + { ( defined $hint ? ( hint => $hint ) : () ) } ), + 2, + 'count w/ spec' ); + is( + $coll->count_documents( + {}, + { ( defined $hint ? ( hint => $hint ) : () ) } ), + 4, + 'count' ); + }; +} + +sub test_find { + my $hint = shift; + + subtest 'find' => sub { + # XXX cant use explain here to check that its actually using the hint + my $cursor = $coll->find( + { category => 'cake', qty => { '$gt' => 15 } }, + { ( defined $hint ? ( hint => $hint ) : () ) } + ); + + my @res = $cursor->all; + + cmp_deeply \@res, + [ + { + _id => 2, + category => "cake", + qty => 25, + type => "ice cream", + }, + ], + 'Got correct result'; + } +} + +sub test_cursor { + my $hint = shift; + + subtest 'cursor' => sub { + # Actually the same as find, just setting the hint after the fact + my $cursor = $coll->find( + { category => 'cake', qty => { '$gt' => 15 } } + ); + + $cursor->hint( $hint ) if defined $hint; + + my @res = $cursor->all; + + cmp_deeply \@res, + [ + { + _id => 2, + category => "cake", + qty => 25, + type => "ice cream", + }, + ], + 'Got correct result'; + } +} + +done_testing; From b25d759e9e3233590a443246d0d044c4d8e49b02 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 17 Sep 2018 17:09:56 +0100 Subject: [PATCH 4/5] PERL-927 append hint coercion tests to collection.t --- t/collection.t | 154 +++++++++++++++++++++++++++++++++++++++++ t/hint-coerce.t | 180 ------------------------------------------------ 2 files changed, 154 insertions(+), 180 deletions(-) delete mode 100644 t/hint-coerce.t diff --git a/t/collection.t b/t/collection.t index 46dfbf03..96577bb9 100644 --- a/t/collection.t +++ b/t/collection.t @@ -1059,4 +1059,158 @@ subtest "sort BSON::Doc" => sub { 'Got correct sort order'; }; +subtest 'hint coercion' => sub { + plan skip_all => "hints unsupported on MongoDB $server_version" + unless $server_version >= v3.6.0; + + subtest "no hint" => sub { + my $index_name = test_hints_setup(); + test_hints( $index_name ); + }; + + subtest "hint string" => sub { + my $index_name = test_hints_setup(); + test_hints( $index_name, $index_name ); + }; + + subtest "hint array" => sub { + my $index_name = test_hints_setup(); + test_hints( $index_name, [ qty => 1, category => 1 ] ); + }; + + subtest "hint IxHash" => sub { + my $index_name = test_hints_setup(); + test_hints( $index_name, Tie::IxHash->new( qty => 1, category => 1 ) ); + }; + + subtest "hint BSON::Doc" => sub { + my $index_name = test_hints_setup(); + test_hints( $index_name, bson_doc( qty => 1, category => 1 ) ); + }; +}; + +sub test_hints { + test_hints_aggregate( @_ ); + test_hints_count_documents( @_ ); + test_hints_find( @_ ); + test_hints_cursor( @_ ); +} + +sub test_hints_setup { + + $coll->drop; + + $coll->insert_many( [ + { _id => 1, category => "cake", type => "chocolate", qty => 10 }, + { _id => 2, category => "cake", type => "ice cream", qty => 25 }, + { _id => 3, category => "pie", type => "boston cream", qty => 20 }, + { _id => 4, category => "pie", type => "blueberry", qty => 15 }, + ] ); + + $coll->indexes->create_one( [ qty => 1, type => 1 ] ); + my $index_name = $coll->indexes->create_one( [qty => 1, category => 1 ] ); + + return $index_name; +} + +sub test_hints_aggregate { + my ( $index_name, $hint ) = @_; + + subtest 'aggregate' => sub { + my $cursor = $coll->aggregate( + [ + { '$sort' => { qty => 1 } }, + { '$match' => { category => 'cake', qty => 10 } }, + { '$sort' => { type => -1 } } ], + { ( defined $hint ? ( hint => $hint ) : () ), explain => 1 } + ); + + my $result = $cursor->next; + + is( ref( $result ), 'HASH', "aggregate with explain returns a hashref" ); + + if ( defined $hint ) { + ok( + scalar( @{ $result->{stages}->[0]->{'$cursor'}->{queryPlanner}->{rejectedPlans} } ) == 0, + "aggregate with hint had no rejectedPlans", + ); + } else { + ok( + scalar( @{ $result->{stages}->[0]->{'$cursor'}->{queryPlanner}->{rejectedPlans} } ) > 0, + "aggregate with no hint had rejectedPlans", + ); + } + }; +} + +sub test_hints_count_documents { + my ( $index_name, $hint ) = @_; + + subtest 'count_document' => sub { + is( + $coll->count_documents( + { category => 'cake', qty => { '$gt' => 0 } }, + { ( defined $hint ? ( hint => $hint ) : () ) } ), + 2, + 'count w/ spec' ); + is( + $coll->count_documents( + {}, + { ( defined $hint ? ( hint => $hint ) : () ) } ), + 4, + 'count' ); + }; +} + +sub test_hints_find { + my ( $index_name, $hint ) = @_; + + subtest 'find' => sub { + # XXX cant use explain here to check that its actually using the hint + my $cursor = $coll->find( + { category => 'cake', qty => { '$gt' => 15 } }, + { ( defined $hint ? ( hint => $hint ) : () ) } + ); + + my @res = $cursor->all; + + cmp_deeply \@res, + [ + { + _id => 2, + category => "cake", + qty => 25, + type => "ice cream", + }, + ], + 'Got correct result'; + } +} + +sub test_hints_cursor { + my ( $index_name, $hint ) = @_; + + subtest 'cursor' => sub { + # Actually the same as find, just setting the hint after the fact + my $cursor = $coll->find( + { category => 'cake', qty => { '$gt' => 15 } } + ); + + $cursor->hint( $hint ) if defined $hint; + + my @res = $cursor->all; + + cmp_deeply \@res, + [ + { + _id => 2, + category => "cake", + qty => 25, + type => "ice cream", + }, + ], + 'Got correct result'; + } +} + done_testing; diff --git a/t/hint-coerce.t b/t/hint-coerce.t deleted file mode 100644 index 8676eea2..00000000 --- a/t/hint-coerce.t +++ /dev/null @@ -1,180 +0,0 @@ -# Copyright 2015 - present MongoDB, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -use strict; -use warnings; -use Test::More 0.96; -use Test::Fatal; -use Test::Deep qw/!blessed/; - -use utf8; -use Tie::IxHash; - -use MongoDB; -use MongoDB::Error; -use BSON::Types ':all'; - -use lib "t/lib"; -use MongoDBTest qw/skip_unless_mongod build_client get_test_db server_version server_type get_capped/; - -skip_unless_mongod(); - -my $conn = build_client(); -my $testdb = get_test_db($conn); -my $server_version = server_version($conn); -my $server_type = server_type($conn); -my $coll = $testdb->get_collection('test_collection'); - -plan skip_all => "hints unsupported on MongoDB $server_version" - unless $server_version >= v3.6.0; - -$coll->insert_many( [ - { _id => 1, category => "cake", type => "chocolate", qty => 10 }, - { _id => 2, category => "cake", type => "ice cream", qty => 25 }, - { _id => 3, category => "pie", type => "boston cream", qty => 20 }, - { _id => 4, category => "pie", type => "blueberry", qty => 15 }, -] ); - -$coll->indexes->create_one( [ qty => 1, type => 1 ] ); -my $index_name = $coll->indexes->create_one( [qty => 1, category => 1 ] ); - -subtest "no hint" => sub { - test_hints(); -}; - -subtest "hint string" => sub { - test_hints( $index_name ); -}; - -subtest "hint array" => sub { - test_hints( [ qty => 1, category => 1 ] ); -}; - -subtest "hint IxHash" => sub { - test_hints( Tie::IxHash->new( qty => 1, category => 1 ) ); -}; - -subtest "hint BSON::Doc" => sub { - test_hints( bson_doc( qty => 1, category => 1 ) ); -}; - -sub test_hints { - my $hint = shift; - test_aggregate( $hint ); - test_count_documents( $hint ); - test_find( $hint ); - test_cursor( $hint ); -} - -sub test_aggregate { - my $hint = shift; - - subtest 'aggregate' => sub { - my $cursor = $coll->aggregate( - [ - { '$sort' => { qty => 1 } }, - { '$match' => { category => 'cake', qty => 10 } }, - { '$sort' => { type => -1 } } ], - { ( defined $hint ? ( hint => $hint ) : () ), explain => 1 } - ); - - my $result = $cursor->next; - - is( ref( $result ), 'HASH', "aggregate with explain returns a hashref" ); - - if ( defined $hint ) { - ok( - scalar( @{ $result->{stages}->[0]->{'$cursor'}->{queryPlanner}->{rejectedPlans} } ) == 0, - "aggregate with hint had no rejectedPlans", - ); - } else { - ok( - scalar( @{ $result->{stages}->[0]->{'$cursor'}->{queryPlanner}->{rejectedPlans} } ) > 0, - "aggregate with no hint had rejectedPlans", - ); - } - }; -} - -sub test_count_documents { - my $hint = shift; - - subtest 'count_document' => sub { - is( - $coll->count_documents( - { category => 'cake', qty => { '$gt' => 0 } }, - { ( defined $hint ? ( hint => $hint ) : () ) } ), - 2, - 'count w/ spec' ); - is( - $coll->count_documents( - {}, - { ( defined $hint ? ( hint => $hint ) : () ) } ), - 4, - 'count' ); - }; -} - -sub test_find { - my $hint = shift; - - subtest 'find' => sub { - # XXX cant use explain here to check that its actually using the hint - my $cursor = $coll->find( - { category => 'cake', qty => { '$gt' => 15 } }, - { ( defined $hint ? ( hint => $hint ) : () ) } - ); - - my @res = $cursor->all; - - cmp_deeply \@res, - [ - { - _id => 2, - category => "cake", - qty => 25, - type => "ice cream", - }, - ], - 'Got correct result'; - } -} - -sub test_cursor { - my $hint = shift; - - subtest 'cursor' => sub { - # Actually the same as find, just setting the hint after the fact - my $cursor = $coll->find( - { category => 'cake', qty => { '$gt' => 15 } } - ); - - $cursor->hint( $hint ) if defined $hint; - - my @res = $cursor->all; - - cmp_deeply \@res, - [ - { - _id => 2, - category => "cake", - qty => 25, - type => "ice cream", - }, - ], - 'Got correct result'; - } -} - -done_testing; From 5976cec79a50ed1d83d16bbf3f7a27c78531e0a8 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Thu, 20 Sep 2018 15:42:48 +0100 Subject: [PATCH 5/5] PERL-927 Move hint test guard for server version --- t/collection.t | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/t/collection.t b/t/collection.t index 96577bb9..114fbb41 100644 --- a/t/collection.t +++ b/t/collection.t @@ -1060,9 +1060,6 @@ subtest "sort BSON::Doc" => sub { }; subtest 'hint coercion' => sub { - plan skip_all => "hints unsupported on MongoDB $server_version" - unless $server_version >= v3.6.0; - subtest "no hint" => sub { my $index_name = test_hints_setup(); test_hints( $index_name ); @@ -1117,6 +1114,9 @@ sub test_hints_aggregate { my ( $index_name, $hint ) = @_; subtest 'aggregate' => sub { + plan skip_all => "hints unsupported for aggregate on MongoDB $server_version" + unless $server_version >= v3.6.0; + my $cursor = $coll->aggregate( [ { '$sort' => { qty => 1 } }, @@ -1166,7 +1166,6 @@ sub test_hints_find { my ( $index_name, $hint ) = @_; subtest 'find' => sub { - # XXX cant use explain here to check that its actually using the hint my $cursor = $coll->find( { category => 'cake', qty => { '$gt' => 15 } }, { ( defined $hint ? ( hint => $hint ) : () ) }