2011-05-01 09:30:17 -04:00
|
|
|
|
|
|
|
|
t = db.idhack
|
|
|
|
|
t.drop()
|
|
|
|
|
|
2014-08-27 15:36:08 -04:00
|
|
|
// Include helpers for analyzing explain output.
|
|
|
|
|
load("jstests/libs/analyze_plan.js");
|
2011-05-01 09:30:17 -04:00
|
|
|
|
|
|
|
|
t.insert( { _id : { x : 1 } , z : 1 } )
|
|
|
|
|
t.insert( { _id : { x : 2 } , z : 2 } )
|
|
|
|
|
t.insert( { _id : { x : 3 } , z : 3 } )
|
|
|
|
|
t.insert( { _id : 1 , z : 4 } )
|
|
|
|
|
t.insert( { _id : 2 , z : 5 } )
|
|
|
|
|
t.insert( { _id : 3 , z : 6 } )
|
|
|
|
|
|
|
|
|
|
assert.eq( 2 , t.findOne( { _id : { x : 2 } } ).z , "A1" )
|
|
|
|
|
assert.eq( 2 , t.find( { _id : { $gte : 2 } } ).count() , "A2" )
|
|
|
|
|
assert.eq( 2 , t.find( { _id : { $gte : 2 } } ).itcount() , "A3" )
|
|
|
|
|
|
|
|
|
|
t.update( { _id : { x : 2 } } , { $set : { z : 7 } } )
|
|
|
|
|
assert.eq( 7 , t.findOne( { _id : { x : 2 } } ).z , "B1" )
|
|
|
|
|
|
|
|
|
|
t.update( { _id : { $gte : 2 } } , { $set : { z : 8 } } , false , true )
|
|
|
|
|
assert.eq( 4 , t.findOne( { _id : 1 } ).z , "C1" )
|
|
|
|
|
assert.eq( 8 , t.findOne( { _id : 2 } ).z , "C2" )
|
|
|
|
|
assert.eq( 8 , t.findOne( { _id : 3 } ).z , "C3" )
|
2014-02-10 14:38:06 -05:00
|
|
|
|
2014-02-10 14:17:17 -05:00
|
|
|
// explain output should show that the ID hack was applied.
|
|
|
|
|
var query = { _id : { x : 2 } };
|
|
|
|
|
var explain = t.find( query ).explain( true );
|
|
|
|
|
print( "explain for " + tojson( query , "" , true ) + " = " + tojson( explain ) );
|
2014-08-27 15:36:08 -04:00
|
|
|
assert.eq( 1 , explain.executionStats.nReturned , "D1" );
|
|
|
|
|
assert.eq( 1 , explain.executionStats.totalKeysExamined , "D2" );
|
|
|
|
|
assert( isIdhack(explain.queryPlanner.winningPlan), "D3" );
|
2014-02-10 14:17:17 -05:00
|
|
|
|
2014-02-10 14:38:06 -05:00
|
|
|
// ID hack cannot be used with hint().
|
|
|
|
|
t.ensureIndex( { _id : 1 , a : 1 } );
|
|
|
|
|
var hintExplain = t.find( query ).hint( { _id : 1 , a : 1 } ).explain();
|
|
|
|
|
print( "explain for hinted query = " + tojson( hintExplain ) );
|
2014-08-27 15:36:08 -04:00
|
|
|
assert( !isIdhack(hintExplain.queryPlanner.winningPlan), "E1" );
|
2014-02-10 14:17:17 -05:00
|
|
|
|
2014-03-04 22:53:26 -05:00
|
|
|
// ID hack cannot be used with skip().
|
|
|
|
|
var skipExplain = t.find( query ).skip(1).explain();
|
|
|
|
|
print( "explain for skip query = " + tojson( skipExplain ) );
|
2014-08-27 15:36:08 -04:00
|
|
|
assert( !isIdhack(skipExplain.queryPlanner.winningPlan), "F1" );
|
2014-03-04 22:53:26 -05:00
|
|
|
|
2014-03-05 10:40:16 -05:00
|
|
|
// Covered query returning _id field only can be handled by ID hack.
|
|
|
|
|
var coveredExplain = t.find( query, { _id : 1 } ).explain();
|
|
|
|
|
print( "explain for covered query = " + tojson( coveredExplain ) );
|
2014-08-27 15:36:08 -04:00
|
|
|
assert( isIdhack(coveredExplain.queryPlanner.winningPlan), "G1" );
|
2014-03-05 10:40:16 -05:00
|
|
|
// Check doc from covered ID hack query.
|
2014-04-28 16:39:33 -04:00
|
|
|
assert.eq( { _id : { x: 2 } }, t.findOne( query, { _id : 1 } ), "G2" );
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Non-covered projection for idhack.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
t.drop();
|
|
|
|
|
t.insert( { _id: 0, a: 0, b: [ { c: 1 }, { c: 2 } ] });
|
|
|
|
|
t.insert( { _id: 1, a: 1, b: [ { c: 3 }, { c: 4 } ] });
|
|
|
|
|
|
|
|
|
|
// Simple inclusion.
|
|
|
|
|
assert.eq( { _id: 1, a: 1 }, t.find( { _id: 1 }, { a: 1 } ).next() );
|
|
|
|
|
assert.eq( { a: 1 }, t.find({ _id: 1 }, { _id: 0, a: 1 } ).next() );
|
|
|
|
|
assert.eq( { _id: 0, a: 0 }, t.find( { _id: 0 }, { _id: 1, a: 1 } ).next() );
|
|
|
|
|
|
|
|
|
|
// Non-simple: exclusion.
|
|
|
|
|
assert.eq( { _id: 1, a: 1 }, t.find( { _id: 1 }, { b: 0 } ).next() );
|
|
|
|
|
assert.eq( { _id: 0, }, t.find( { _id: 0 }, { a: 0, b: 0 } ).next() );
|
|
|
|
|
|
|
|
|
|
// Non-simple: dotted fields.
|
|
|
|
|
assert.eq( { b: [ { c: 1 }, { c: 2 } ] }, t.find( { _id: 0 }, { _id: 0, "b.c": 1 } ).next() );
|
|
|
|
|
assert.eq( { _id: 1 }, t.find( { _id: 1 }, { "foo.bar": 1 } ).next() );
|
|
|
|
|
|
|
|
|
|
// Non-simple: elemMatch projection.
|
|
|
|
|
assert.eq( { _id: 1, b: [ { c: 4 } ] },
|
|
|
|
|
t.find( { _id: 1 }, { b: { $elemMatch: { c: 4 } } } ).next() );
|
|
|
|
|
|
2015-07-23 18:57:46 -04:00
|
|
|
// Non-simple: .returnKey().
|
|
|
|
|
assert.eq( { _id: 1 }, t.find( { _id: 1 } ).returnKey().next() );
|
2014-04-28 16:39:33 -04:00
|
|
|
|
2015-07-23 18:57:46 -04:00
|
|
|
// Non-simple: .returnKey() overrides other projections.
|
|
|
|
|
assert.eq( { _id: 1 }, t.find( { _id: 1 }, { a: 1 } ).returnKey().next() );
|