diff options
author | Jacob Evans <jacob.evans@10gen.com> | 2020-10-09 22:56:39 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-10 04:59:28 +0000 |
commit | ea38428f0c6742c7c2c7f677e73d79e17a2aab96 (patch) | |
tree | feff32f47baa3ac3c8588323ef8be8ebff1b9964 /jstests | |
parent | b6fb02d5780247fa294c1f5cc432a80722b4c21a (diff) | |
download | mongo-r4.2.11.tar.gz |
SERVER-51303 Fix lookup match absorbtion optimization for $typer4.2.11-rc1r4.2.11
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/aggregation/sources/lookup/lookup_absorb_match.js | 268 |
1 files changed, 218 insertions, 50 deletions
diff --git a/jstests/aggregation/sources/lookup/lookup_absorb_match.js b/jstests/aggregation/sources/lookup/lookup_absorb_match.js index 1d85817970f..3c1daaf624f 100644 --- a/jstests/aggregation/sources/lookup/lookup_absorb_match.js +++ b/jstests/aggregation/sources/lookup/lookup_absorb_match.js @@ -1,6 +1,6 @@ /** - * Tests that a $match with a geo expression still returns the correct results if it has been - * absorbed by a $lookup. + * Tests that $match stages with a variety of expressions still return the correct results if they + * have been absorbed by $lookup stages. * * Accessed collections cannot be implicitly sharded because you cannot $lookup into a sharded * collection. @@ -13,8 +13,16 @@ let testDB = db.getSiblingDB("lookup_absorb_match"); testDB.dropDatabase(); let locations = testDB.getCollection("locations"); -assert.writeOK(locations.insert({_id: "doghouse", coordinates: [25.0, 60.0]})); -assert.writeOK(locations.insert({_id: "bullpen", coordinates: [-25.0, -60.0]})); +assert.commandWorked(locations.insert({ + _id: "doghouse", + coordinates: [25.0, 60.0], + extra: {breeds: ["terrier", "dachshund", "bulldog"]} +})); +assert.commandWorked(locations.insert({ + _id: "bullpen", + coordinates: [-25.0, -60.0], + extra: {breeds: "Scottish Highland", feeling: "bullish"} +})); let animals = testDB.getCollection("animals"); assert.writeOK(animals.insert({_id: "dog", locationId: "doghouse"})); @@ -25,32 +33,33 @@ assert.writeOK(animals.insert({_id: "bull", locationId: "bullpen"})); let result = testDB.animals .aggregate([ { - $lookup: { - from: "locations", - localField: "locationId", - foreignField: "_id", - as: "location" - } + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } }, {$unwind: "$location"}, { - $match: { - "location.coordinates": { - $geoWithin: { - $geometry: { - type: "MultiPolygon", - coordinates: [[[ - [20.0, 70.0], - [30.0, 70.0], - [30.0, 50.0], - [20.0, 50.0], - [20.0, 70.0] - ]]] - } - } - } - } - } + $match: { + "location.coordinates": { + $geoWithin: { + $geometry: { + type: "MultiPolygon", + coordinates: [[[ + [20.0, 70.0], + [30.0, 70.0], + [30.0, 50.0], + [20.0, 50.0], + [20.0, 70.0] + ]]] + } + } + } + } + }, + {$project: {"location.extra": false}} ]) .toArray(); let expected = @@ -61,35 +70,194 @@ assert.eq(result, expected); result = testDB.animals .aggregate([ { - $lookup: { - from: "locations", - localField: "locationId", - foreignField: "_id", - as: "location" - } + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } }, {$unwind: "$location"}, { - $match: { - "location.coordinates": { - $geoIntersects: { - $geometry: { - type: "MultiPolygon", - coordinates: [[[ - [-20.0, -70.0], - [-30.0, -70.0], - [-30.0, -50.0], - [-20.0, -50.0], - [-20.0, -70.0] - ]]] - } - } - } - } - } + $match: { + "location.coordinates": { + $geoIntersects: { + $geometry: { + type: "MultiPolygon", + coordinates: [[[ + [-20.0, -70.0], + [-30.0, -70.0], + [-30.0, -50.0], + [-20.0, -50.0], + [-20.0, -70.0] + ]]] + } + } + } + } + }, + {$project: {"location.extra": false}} ]) .toArray(); expected = [{_id: "bull", locationId: "bullpen", location: {_id: "bullpen", coordinates: [-25.0, -60.0]}}]; assert.eq(result, expected); + +// Test that a $match with $type works as expected when absorbed by a $lookup. +result = testDB.animals + .aggregate([ + { + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } + }, + {$unwind: "$location"}, + { + $match: { + "location.extra.breeds": { + $type: "array" + } + } + }, + {$project: {"location.extra": false}} + ]) + .toArray(); +expected = + [{_id: "dog", locationId: "doghouse", location: {_id: "doghouse", coordinates: [25.0, 60.0]}}]; +assert.eq(result, expected); + +// Test that a $match with $jsonSchema works as expected although ineligable for absorbtion by a +// $lookup. +result = testDB.animals + .aggregate([ + { + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } + }, + {$unwind: "$location"}, + { + $match: { + $jsonSchema: { + properties: {location: { + properties: {extra: { + properties: {breeds: {type: "string"}} + }} + }} + } + } + }, + {$project: {"location.extra": false}} + ]) + .toArray(); +expected = + [{_id: "bull", locationId: "bullpen", location: {_id: "bullpen", coordinates: [-25.0, -60.0]}}]; +assert.eq(result, expected); + +// Test that a more complex $match with $jsonSchema works as expected although ineligable for +// absorbtion by a $lookup. +result = testDB.animals + .aggregate([ + { + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } + }, + {$unwind: "$location"}, + { + $match: { + $jsonSchema: { + properties: {location: {properties: {extra: {minProperties: 2}}}} + } + } + }, + {$project: {"location.extra": false}} + ]) + .toArray(); +expected = + [{_id: "bull", locationId: "bullpen", location: {_id: "bullpen", coordinates: [-25.0, -60.0]}}]; +assert.eq(result, expected); + +// Test that a $match with $alwaysTrue works as expected although ineligable for absorbtion by a +// $lookup. +result = testDB.animals + .aggregate([ + { + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } + }, + {$unwind: "$location"}, + { + $match: {$alwaysTrue: 1} + }, + {$project: {"location.extra": false}}, + {$sort: {_id: 1}} + ]) + .toArray(); +expected = [ + {_id: "bull", locationId: "bullpen", location: {_id: "bullpen", coordinates: [-25.0, -60.0]}}, + {_id: "dog", locationId: "doghouse", location: {_id: "doghouse", coordinates: [25.0, 60.0]}} +]; +assert.eq(result, expected); + +// Test that a $match with $alwaysFalse works as expected although ineligable for absorbtion by a +// $lookup. +result = testDB.animals + .aggregate([ + { + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } + }, + {$unwind: "$location"}, + { + $match: {$alwaysFalse: 1} + }, + {$project: {"location.extra": false}}, + ]) + .toArray(); +expected = []; +assert.eq(result, expected); + +// Test that a $match with $expr works as expected although ineligable for absorbtion by a $lookup. +result = testDB.animals + .aggregate([ + { + $lookup: { + from: "locations", + localField: "locationId", + foreignField: "_id", + as: "location" + } + }, + {$unwind: "$location"}, + { + $match: { + $expr: { + $in: [25.0, "$location.coordinates"] + } + } + }, + {$project: {"location.extra": false}}, + ]) + .toArray(); +expected = + [{_id: "dog", locationId: "doghouse", location: {_id: "doghouse", coordinates: [25.0, 60.0]}}]; +assert.eq(result, expected); }()); |