Hide
Create a timeseries collection
db.createCollection( "nT", { timeseries: { timeField: "timestamp", metaField: "metadata" } })
Insert a few documents
db.nT.insertMany([
{ timestamp: ISODate("2021-05-18T00:00:00.000Z"), _id: 'a_null', a: null },
{ timestamp: ISODate("2021-05-18T00:00:01.000Z"), _id: 'a_object', a: {} },
{ timestamp: ISODate("2021-05-18T00:00:02.000Z"), _id: 'a_empty_array', a: [] },
{ timestamp: ISODate("2021-05-18T00:00:03.000Z"), _id: 'a_nulls_array', a: [null, null] }
])
Count the number of documents that have `a: {$eq: null} `
db.runCommand({count: "nT", query: { a: {$eq: null} }})
In master the above query returns 2 (a:null and a:[null, null]) while when we run it with block TypeMatch (PR with the code) it returns 3 (a:null , a:[null, null] and a: []).
SBE Plan with block TypeMatch
slotBasedPlan: {
slots: '$$RESULT=s11 env: { s6 = Nothing (nothing) }',
stages: '[4] project [s11 = makeBsonObj(MakeObjSpec([count], [_id, count], Closed, RetNothing), null, true, Nothing, s8)] \n' +
'[3] project [s10 = null] \n' +
'[3] group [] [s8 = sum(1)] spillSlots[s9] mergingExprs[sum(s9)] \n' +
'[2] block_to_row blocks[s3] row[s7] s5 \n' +
'[2] filter {!(valueBlockNone(s5, true))} \n' +
'[2] project [s5 = \n' +
' let [\n' +
' l101.0 = cellBlockGetFlatValuesBlock(s4) \n' +
' ] \n' +
' in cellFoldValues_F(valueBlockFillEmpty(valueBlockEqScalar(\n' +
' let [\n' +
' l102.0 = valueBlockFillEmpty(valueBlockTypeMatch(l101.0, 1088), true) \n' +
' ] \n' +
' in valueBlockCombine(valueBlockNewFill(\n' +
' if valueBlockNone(l102.0, true) \n' +
' then Nothing \n' +
' else null \n' +
' , valueBlockSize(l102.0)), move(l101.0), l102.0) \n' +
' , null), false), s4) \n' +
'] \n' +
'[2] ts_bucket_to_cellblock s1 pathReqs[s3 = ProjectPath(Get(a)/Id), s4 = FilterPath(Get(a)/Traverse/Id)] \n' +
'[1] scan s1 s2 none none none none none none lowPriority [] @"3fe22bd2-503a-4920-a760-5cf69eecbd00" true false '
}
SBE Plan with scalar TypeMatch
slotBasedPlan: {
slots: '$$RESULT=s10 env: { s6 = Nothing (nothing) }',
stages: '[4] project [s10 = makeBsonObj(MakeObjSpec([count], [_id, count], Closed, RetNothing), null, true, Nothing, s7)] \n' +
'[3] project [s9 = null] \n' +
'[3] group [] [s7 = sum(1)] spillSlots[s8] mergingExprs[sum(s8)] \n' +
'[2] filter {traverseF(s5, lambda(l101.0) { ((\n' +
' if (typeMatch(l101.0, 1088) ?: true) \n' +
' then null \n' +
' else move(l101.0) \n' +
'== null) ?: false) }, false)} \n' +
'[2] block_to_row blocks[s3] row[s5] \n' +
'[2] ts_bucket_to_cellblock s1 pathReqs[s3 = ProjectPath(Get(a)/Id), s4 = FilterPath(Get(a)/Traverse/Id)] \n' +
'[1] scan s1 s2 none none none none none none lowPriority [] @"3fe22bd2-503a-4920-a760-5cf69eecbd00" true false '
}
Query used to get the plans : `db.runCommand({explain: {count: "nT", query: { a: {$eq: null} }}})`
Show
Create a timeseries collection
db.createCollection( "nT" , { timeseries: { timeField: "timestamp" , metaField: "metadata" } })
Insert a few documents
db.nT.insertMany([
{ timestamp: ISODate( "2021-05-18T00:00:00.000Z" ), _id: 'a_null' , a: null },
{ timestamp: ISODate( "2021-05-18T00:00:01.000Z" ), _id: 'a_object' , a: {} },
{ timestamp: ISODate( "2021-05-18T00:00:02.000Z" ), _id: 'a_empty_array' , a: [] },
{ timestamp: ISODate( "2021-05-18T00:00:03.000Z" ), _id: 'a_nulls_array' , a: [ null , null ] }
])
Count the number of documents that have `a: {$eq: null} `
db.runCommand({count: "nT" , query: { a: {$eq: null } }})
In master the above query returns 2 (a:null and a: [null, null] ) while when we run it with block TypeMatch ( PR with the code ) it returns 3 (a:null , a: [null, null] and a: []).
SBE Plan with block TypeMatch
slotBasedPlan: {
slots: '$$RESULT=s11 env: { s6 = Nothing (nothing) }' ,
stages: '[4] project [s11 = makeBsonObj(MakeObjSpec([count], [_id, count], Closed, RetNothing), null , true , Nothing, s8)] \n' +
'[3] project [s10 = null ] \n' +
'[3] group [] [s8 = sum(1)] spillSlots[s9] mergingExprs[sum(s9)] \n' +
'[2] block_to_row blocks[s3] row[s7] s5 \n' +
'[2] filter {!(valueBlockNone(s5, true ))} \n' +
'[2] project [s5 = \n' +
' let [\n' +
' l101.0 = cellBlockGetFlatValuesBlock(s4) \n' +
' ] \n' +
' in cellFoldValues_F(valueBlockFillEmpty(valueBlockEqScalar(\n' +
' let [\n' +
' l102.0 = valueBlockFillEmpty(valueBlockTypeMatch(l101.0, 1088), true ) \n' +
' ] \n' +
' in valueBlockCombine(valueBlockNewFill(\n' +
' if valueBlockNone(l102.0, true ) \n' +
' then Nothing \n' +
' else null \n' +
' , valueBlockSize(l102.0)), move(l101.0), l102.0) \n' +
' , null ), false ), s4) \n' +
'] \n' +
'[2] ts_bucket_to_cellblock s1 pathReqs[s3 = ProjectPath(Get(a)/Id), s4 = FilterPath(Get(a)/Traverse/Id)] \n' +
'[1] scan s1 s2 none none none none none none lowPriority [] @ "3fe22bd2-503a-4920-a760-5cf69eecbd00" true false '
}
SBE Plan with scalar TypeMatch
slotBasedPlan: {
slots: '$$RESULT=s10 env: { s6 = Nothing (nothing) }' ,
stages: '[4] project [s10 = makeBsonObj(MakeObjSpec([count], [_id, count], Closed, RetNothing), null , true , Nothing, s7)] \n' +
'[3] project [s9 = null ] \n' +
'[3] group [] [s7 = sum(1)] spillSlots[s8] mergingExprs[sum(s8)] \n' +
'[2] filter {traverseF(s5, lambda(l101.0) { ((\n' +
' if (typeMatch(l101.0, 1088) ?: true ) \n' +
' then null \n' +
' else move(l101.0) \n' +
'== null ) ?: false ) }, false )} \n' +
'[2] block_to_row blocks[s3] row[s5] \n' +
'[2] ts_bucket_to_cellblock s1 pathReqs[s3 = ProjectPath(Get(a)/Id), s4 = FilterPath(Get(a)/Traverse/Id)] \n' +
'[1] scan s1 s2 none none none none none none lowPriority [] @ "3fe22bd2-503a-4920-a760-5cf69eecbd00" true false '
}
Query used to get the plans : `db.runCommand({explain: {count: "nT", query: { a: {$eq: null} }}})`