summaryrefslogtreecommitdiff
path: root/jstests/sharding/agg_sort.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/sharding/agg_sort.js')
-rw-r--r--jstests/sharding/agg_sort.js420
1 files changed, 207 insertions, 213 deletions
diff --git a/jstests/sharding/agg_sort.js b/jstests/sharding/agg_sort.js
index 2aebb8e0ded..0ee78631ec0 100644
--- a/jstests/sharding/agg_sort.js
+++ b/jstests/sharding/agg_sort.js
@@ -1,225 +1,219 @@
// Tests that the sort order is obeyed when an aggregation requests sorted results that are
// scattered across multiple shards.
(function() {
- 'use strict';
-
- const shardingTest = new ShardingTest({shards: 2});
-
- const db = shardingTest.getDB("test");
- const coll = db.sharded_agg_sort;
- coll.drop();
-
- assert.commandWorked(shardingTest.s0.adminCommand({enableSharding: db.getName()}));
- shardingTest.ensurePrimaryShard(db.getName(), shardingTest.shard1.shardName);
- assert.commandWorked(
- shardingTest.s0.adminCommand({shardCollection: coll.getFullName(), key: {_id: 1}}));
-
- const nDocs = 10;
- const yValues = [
- "abc",
- "ABC",
- null,
- 1,
- NumberLong(2),
- NumberDecimal(-20),
- MinKey,
- MaxKey,
- BinData(0, ""),
- [3, 4],
- ];
- const bulkOp = coll.initializeOrderedBulkOp();
- for (var i = 0; i < nDocs; ++i) {
- bulkOp.insert({_id: i, x: Math.floor(i / 2), y: yValues[i]});
- }
- assert.writeOK(bulkOp.execute());
-
- // Split the data into 3 chunks
- assert.commandWorked(
- shardingTest.s0.adminCommand({split: coll.getFullName(), middle: {_id: 3}}));
- assert.commandWorked(
- shardingTest.s0.adminCommand({split: coll.getFullName(), middle: {_id: 6}}));
-
- // Migrate the middle chunk to another shard
- assert.commandWorked(shardingTest.s0.adminCommand({
- movechunk: coll.getFullName(),
- find: {_id: 5},
- to: shardingTest.getOther(shardingTest.getPrimaryShard(db.getName())).name
- }));
-
- function assertResultsEqual({actual, expected}) {
- const resultsAsString = " actual: " + tojson(actual) + "\n expected: " + tojson(expected);
- assert.eq(
- actual.length, expected.length, `different number of results:\n${resultsAsString}`);
- for (let i = 0; i < actual.length; i++) {
- assert.eq(
- actual[i], expected[i], `different results at index ${i}:\n${resultsAsString}`);
- }
+'use strict';
+
+const shardingTest = new ShardingTest({shards: 2});
+
+const db = shardingTest.getDB("test");
+const coll = db.sharded_agg_sort;
+coll.drop();
+
+assert.commandWorked(shardingTest.s0.adminCommand({enableSharding: db.getName()}));
+shardingTest.ensurePrimaryShard(db.getName(), shardingTest.shard1.shardName);
+assert.commandWorked(
+ shardingTest.s0.adminCommand({shardCollection: coll.getFullName(), key: {_id: 1}}));
+
+const nDocs = 10;
+const yValues = [
+ "abc",
+ "ABC",
+ null,
+ 1,
+ NumberLong(2),
+ NumberDecimal(-20),
+ MinKey,
+ MaxKey,
+ BinData(0, ""),
+ [3, 4],
+];
+const bulkOp = coll.initializeOrderedBulkOp();
+for (var i = 0; i < nDocs; ++i) {
+ bulkOp.insert({_id: i, x: Math.floor(i / 2), y: yValues[i]});
+}
+assert.writeOK(bulkOp.execute());
+
+// Split the data into 3 chunks
+assert.commandWorked(shardingTest.s0.adminCommand({split: coll.getFullName(), middle: {_id: 3}}));
+assert.commandWorked(shardingTest.s0.adminCommand({split: coll.getFullName(), middle: {_id: 6}}));
+
+// Migrate the middle chunk to another shard
+assert.commandWorked(shardingTest.s0.adminCommand({
+ movechunk: coll.getFullName(),
+ find: {_id: 5},
+ to: shardingTest.getOther(shardingTest.getPrimaryShard(db.getName())).name
+}));
+
+function assertResultsEqual({actual, expected}) {
+ const resultsAsString = " actual: " + tojson(actual) + "\n expected: " + tojson(expected);
+ assert.eq(actual.length, expected.length, `different number of results:\n${resultsAsString}`);
+ for (let i = 0; i < actual.length; i++) {
+ assert.eq(actual[i], expected[i], `different results at index ${i}:\n${resultsAsString}`);
}
+}
- function testSorts() {
- // Test a basic sort by _id.
- assertResultsEqual({
- actual: coll.aggregate([{$sort: {_id: 1}}]).toArray(),
- expected: [
- {_id: 0, x: 0, y: "abc"},
- {_id: 1, x: 0, y: "ABC"},
- {_id: 2, x: 1, y: null},
- {_id: 3, x: 1, y: 1},
- {_id: 4, x: 2, y: NumberLong(2)},
- {_id: 5, x: 2, y: NumberDecimal(-20)},
- {_id: 6, x: 3, y: MinKey},
- {_id: 7, x: 3, y: MaxKey},
- {_id: 8, x: 4, y: BinData(0, "")},
- {_id: 9, x: 4, y: [3, 4]},
- ],
- });
- assertResultsEqual({
- actual: coll.aggregate([{$sort: {_id: 1}}, {$project: {_id: 1}}]).toArray(),
- expected: new Array(nDocs).fill().map(function(_, index) {
- return {_id: index};
- }),
- });
-
- // Test a compound sort.
- assertResultsEqual({
- actual: coll.aggregate([{$sort: {x: 1, y: 1}}]).toArray(),
- expected: [
- {_id: 1, x: 0, y: "ABC"},
- {_id: 0, x: 0, y: "abc"},
- {_id: 2, x: 1, y: null},
- {_id: 3, x: 1, y: 1},
- {_id: 5, x: 2, y: NumberDecimal(-20)},
- {_id: 4, x: 2, y: NumberLong(2)},
- {_id: 6, x: 3, y: MinKey},
- {_id: 7, x: 3, y: MaxKey},
- {_id: 9, x: 4, y: [3, 4]},
- {_id: 8, x: 4, y: BinData(0, "")},
- ],
- });
- assertResultsEqual({
- actual:
- coll.aggregate([{$sort: {x: 1, y: 1}}, {$project: {_id: 0, x: 1, y: 1}}]).toArray(),
- expected: [
- {x: 0, y: "ABC"},
- {x: 0, y: "abc"},
- {x: 1, y: null},
- {x: 1, y: 1},
- {x: 2, y: NumberDecimal(-20)},
- {x: 2, y: NumberLong(2)},
- {x: 3, y: MinKey},
- {x: 3, y: MaxKey},
- {x: 4, y: [3, 4]},
- {x: 4, y: BinData(0, "")},
- ],
- });
-
- // Test a compound sort with a missing field.
- assertResultsEqual({
- actual: coll.aggregate({$sort: {missing: -1, x: 1, _id: -1}}).toArray(),
- expected: [
- {_id: 1, x: 0, y: "ABC"},
- {_id: 0, x: 0, y: "abc"},
- {_id: 3, x: 1, y: 1},
- {_id: 2, x: 1, y: null},
- {_id: 5, x: 2, y: NumberDecimal(-20)},
- {_id: 4, x: 2, y: NumberLong(2)},
- {_id: 7, x: 3, y: MaxKey},
- {_id: 6, x: 3, y: MinKey},
- {_id: 9, x: 4, y: [3, 4]},
- {_id: 8, x: 4, y: BinData(0, "")},
- ]
- });
- }
- testSorts();
- assert.commandWorked(coll.createIndex({x: 1}));
- testSorts();
- assert.commandWorked(coll.createIndex({x: 1, y: 1}));
- testSorts();
- assert.commandWorked(coll.createIndex({missing: 1, x: -1}));
- testSorts();
- assert.commandWorked(coll.createIndex({missing: -1, x: 1, _id: -1}));
- testSorts();
-
- // Test that a sort including the text score is merged properly in a sharded cluster.
- const textColl = db.sharded_agg_sort_text;
-
- assert.commandWorked(
- shardingTest.s0.adminCommand({shardCollection: textColl.getFullName(), key: {_id: 1}}));
-
- assert.writeOK(textColl.insert([
- {_id: 0, text: "apple"},
- {_id: 1, text: "apple orange banana apple"},
- {_id: 2, text: "apple orange"},
- {_id: 3, text: "apple orange banana apple apple banana"},
- {_id: 4, text: "apple orange banana"},
- {_id: 5, text: "apple orange banana apple apple"},
- ]));
-
- // Split the data into 3 chunks
- assert.commandWorked(
- shardingTest.s0.adminCommand({split: textColl.getFullName(), middle: {_id: 2}}));
- assert.commandWorked(
- shardingTest.s0.adminCommand({split: textColl.getFullName(), middle: {_id: 4}}));
-
- // Migrate the middle chunk to another shard
- assert.commandWorked(shardingTest.s0.adminCommand({
- movechunk: textColl.getFullName(),
- find: {_id: 3},
- to: shardingTest.getOther(shardingTest.getPrimaryShard(db.getName())).name
- }));
-
- assert.commandWorked(textColl.createIndex({text: "text"}));
+function testSorts() {
+ // Test a basic sort by _id.
assertResultsEqual({
- actual: textColl
- .aggregate([
- {$match: {$text: {$search: "apple banana orange"}}},
- {$sort: {x: {$meta: "textScore"}}}
- ])
- .toArray(),
+ actual: coll.aggregate([{$sort: {_id: 1}}]).toArray(),
expected: [
- {_id: 3, text: "apple orange banana apple apple banana"},
- {_id: 5, text: "apple orange banana apple apple"},
- {_id: 1, text: "apple orange banana apple"},
- {_id: 4, text: "apple orange banana"},
- {_id: 2, text: "apple orange"},
- {_id: 0, text: "apple"},
+ {_id: 0, x: 0, y: "abc"},
+ {_id: 1, x: 0, y: "ABC"},
+ {_id: 2, x: 1, y: null},
+ {_id: 3, x: 1, y: 1},
+ {_id: 4, x: 2, y: NumberLong(2)},
+ {_id: 5, x: 2, y: NumberDecimal(-20)},
+ {_id: 6, x: 3, y: MinKey},
+ {_id: 7, x: 3, y: MaxKey},
+ {_id: 8, x: 4, y: BinData(0, "")},
+ {_id: 9, x: 4, y: [3, 4]},
],
});
+ assertResultsEqual({
+ actual: coll.aggregate([{$sort: {_id: 1}}, {$project: {_id: 1}}]).toArray(),
+ expected: new Array(nDocs).fill().map(function(_, index) {
+ return {_id: index};
+ }),
+ });
- function assertSortedByMetaField(results) {
- for (let i = 0; i < results.length - 1; ++i) {
- assert(results[i].hasOwnProperty("meta"),
- `Expected all results to have "meta" field, found one without it at index ${i}`);
- assert.gte(
- results[i].meta,
- results[i + 1].meta,
- `Expected results to be sorted by "meta" field, descending. Detected unsorted` +
- ` results at index ${i}, entire result set: ${tojson(results)}`);
- }
- }
+ // Test a compound sort.
+ assertResultsEqual({
+ actual: coll.aggregate([{$sort: {x: 1, y: 1}}]).toArray(),
+ expected: [
+ {_id: 1, x: 0, y: "ABC"},
+ {_id: 0, x: 0, y: "abc"},
+ {_id: 2, x: 1, y: null},
+ {_id: 3, x: 1, y: 1},
+ {_id: 5, x: 2, y: NumberDecimal(-20)},
+ {_id: 4, x: 2, y: NumberLong(2)},
+ {_id: 6, x: 3, y: MinKey},
+ {_id: 7, x: 3, y: MaxKey},
+ {_id: 9, x: 4, y: [3, 4]},
+ {_id: 8, x: 4, y: BinData(0, "")},
+ ],
+ });
+ assertResultsEqual({
+ actual: coll.aggregate([{$sort: {x: 1, y: 1}}, {$project: {_id: 0, x: 1, y: 1}}]).toArray(),
+ expected: [
+ {x: 0, y: "ABC"},
+ {x: 0, y: "abc"},
+ {x: 1, y: null},
+ {x: 1, y: 1},
+ {x: 2, y: NumberDecimal(-20)},
+ {x: 2, y: NumberLong(2)},
+ {x: 3, y: MinKey},
+ {x: 3, y: MaxKey},
+ {x: 4, y: [3, 4]},
+ {x: 4, y: BinData(0, "")},
+ ],
+ });
- assertSortedByMetaField(textColl
- .aggregate([
- {$match: {$text: {$search: "apple banana orange"}}},
- {$sort: {x: {$meta: "textScore"}}},
- {$project: {_id: 0, meta: {$meta: "textScore"}}},
- ])
- .toArray());
-
- assertSortedByMetaField(textColl
- .aggregate([
- {$match: {$text: {$search: "apple banana orange"}}},
- {$project: {_id: 0, meta: {$meta: "textScore"}}},
- {$sort: {meta: -1}},
- ])
- .toArray());
-
- assertSortedByMetaField(textColl
- .aggregate([
- {$sample: {size: 10}},
- {$project: {_id: 0, meta: {$meta: "randVal"}}},
- ])
- .toArray());
-
- shardingTest.stop();
+ // Test a compound sort with a missing field.
+ assertResultsEqual({
+ actual: coll.aggregate({$sort: {missing: -1, x: 1, _id: -1}}).toArray(),
+ expected: [
+ {_id: 1, x: 0, y: "ABC"},
+ {_id: 0, x: 0, y: "abc"},
+ {_id: 3, x: 1, y: 1},
+ {_id: 2, x: 1, y: null},
+ {_id: 5, x: 2, y: NumberDecimal(-20)},
+ {_id: 4, x: 2, y: NumberLong(2)},
+ {_id: 7, x: 3, y: MaxKey},
+ {_id: 6, x: 3, y: MinKey},
+ {_id: 9, x: 4, y: [3, 4]},
+ {_id: 8, x: 4, y: BinData(0, "")},
+ ]
+ });
+}
+testSorts();
+assert.commandWorked(coll.createIndex({x: 1}));
+testSorts();
+assert.commandWorked(coll.createIndex({x: 1, y: 1}));
+testSorts();
+assert.commandWorked(coll.createIndex({missing: 1, x: -1}));
+testSorts();
+assert.commandWorked(coll.createIndex({missing: -1, x: 1, _id: -1}));
+testSorts();
+
+// Test that a sort including the text score is merged properly in a sharded cluster.
+const textColl = db.sharded_agg_sort_text;
+
+assert.commandWorked(
+ shardingTest.s0.adminCommand({shardCollection: textColl.getFullName(), key: {_id: 1}}));
+
+assert.writeOK(textColl.insert([
+ {_id: 0, text: "apple"},
+ {_id: 1, text: "apple orange banana apple"},
+ {_id: 2, text: "apple orange"},
+ {_id: 3, text: "apple orange banana apple apple banana"},
+ {_id: 4, text: "apple orange banana"},
+ {_id: 5, text: "apple orange banana apple apple"},
+]));
+
+// Split the data into 3 chunks
+assert.commandWorked(
+ shardingTest.s0.adminCommand({split: textColl.getFullName(), middle: {_id: 2}}));
+assert.commandWorked(
+ shardingTest.s0.adminCommand({split: textColl.getFullName(), middle: {_id: 4}}));
+
+// Migrate the middle chunk to another shard
+assert.commandWorked(shardingTest.s0.adminCommand({
+ movechunk: textColl.getFullName(),
+ find: {_id: 3},
+ to: shardingTest.getOther(shardingTest.getPrimaryShard(db.getName())).name
+}));
+
+assert.commandWorked(textColl.createIndex({text: "text"}));
+assertResultsEqual({
+ actual: textColl
+ .aggregate([
+ {$match: {$text: {$search: "apple banana orange"}}},
+ {$sort: {x: {$meta: "textScore"}}}
+ ])
+ .toArray(),
+ expected: [
+ {_id: 3, text: "apple orange banana apple apple banana"},
+ {_id: 5, text: "apple orange banana apple apple"},
+ {_id: 1, text: "apple orange banana apple"},
+ {_id: 4, text: "apple orange banana"},
+ {_id: 2, text: "apple orange"},
+ {_id: 0, text: "apple"},
+ ],
+});
+
+function assertSortedByMetaField(results) {
+ for (let i = 0; i < results.length - 1; ++i) {
+ assert(results[i].hasOwnProperty("meta"),
+ `Expected all results to have "meta" field, found one without it at index ${i}`);
+ assert.gte(results[i].meta,
+ results[i + 1].meta,
+ `Expected results to be sorted by "meta" field, descending. Detected unsorted` +
+ ` results at index ${i}, entire result set: ${tojson(results)}`);
+ }
+}
+
+assertSortedByMetaField(textColl
+ .aggregate([
+ {$match: {$text: {$search: "apple banana orange"}}},
+ {$sort: {x: {$meta: "textScore"}}},
+ {$project: {_id: 0, meta: {$meta: "textScore"}}},
+ ])
+ .toArray());
+
+assertSortedByMetaField(textColl
+ .aggregate([
+ {$match: {$text: {$search: "apple banana orange"}}},
+ {$project: {_id: 0, meta: {$meta: "textScore"}}},
+ {$sort: {meta: -1}},
+ ])
+ .toArray());
+
+assertSortedByMetaField(textColl
+ .aggregate([
+ {$sample: {size: 10}},
+ {$project: {_id: 0, meta: {$meta: "randVal"}}},
+ ])
+ .toArray());
+
+shardingTest.stop();
})();