mirror of https://github.com/mongodb/mongo
246 lines
7.2 KiB
JavaScript
246 lines
7.2 KiB
JavaScript
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
import {findChunksUtil} from "jstests/sharding/libs/find_chunks_util.js";
|
|
|
|
// Values have to be sorted - you must have exactly 6 values in each array
|
|
let types = [
|
|
{name: "string", values: ["allan", "bob", "eliot", "joe", "mark", "sara"], keyfield: "k"},
|
|
{name: "double", values: [1.2, 3.5, 4.5, 4.6, 6.7, 9.9], keyfield: "a"},
|
|
{
|
|
name: "date",
|
|
values: [
|
|
new Date(1000000),
|
|
new Date(2000000),
|
|
new Date(3000000),
|
|
new Date(4000000),
|
|
new Date(5000000),
|
|
new Date(6000000),
|
|
],
|
|
keyfield: "a",
|
|
},
|
|
{name: "string_id", values: ["allan", "bob", "eliot", "joe", "mark", "sara"], keyfield: "_id"},
|
|
{name: "embedded 1", values: ["allan", "bob", "eliot", "joe", "mark", "sara"], keyfield: "a.b"},
|
|
{
|
|
name: "embedded 2",
|
|
values: ["allan", "bob", "eliot", "joe", "mark", "sara"],
|
|
keyfield: "a.b.c",
|
|
},
|
|
{
|
|
name: "object",
|
|
values: [
|
|
{a: 1, b: 1.2},
|
|
{a: 1, b: 3.5},
|
|
{a: 1, b: 4.5},
|
|
{a: 2, b: 1.2},
|
|
{a: 2, b: 3.5},
|
|
{a: 2, b: 4.5},
|
|
],
|
|
keyfield: "o",
|
|
},
|
|
{
|
|
name: "compound",
|
|
values: [
|
|
{a: 1, b: 1.2},
|
|
{a: 1, b: 3.5},
|
|
{a: 1, b: 4.5},
|
|
{a: 2, b: 1.2},
|
|
{a: 2, b: 3.5},
|
|
{a: 2, b: 4.5},
|
|
],
|
|
keyfield: "o",
|
|
compound: true,
|
|
},
|
|
{
|
|
name: "oid_id",
|
|
values: [ObjectId(), ObjectId(), ObjectId(), ObjectId(), ObjectId(), ObjectId()],
|
|
keyfield: "_id",
|
|
},
|
|
{
|
|
name: "oid_other",
|
|
values: [ObjectId(), ObjectId(), ObjectId(), ObjectId(), ObjectId(), ObjectId()],
|
|
keyfield: "o",
|
|
},
|
|
];
|
|
|
|
let s = new ShardingTest({name: "key_many", shards: 2});
|
|
|
|
assert.commandWorked(s.s0.adminCommand({enableSharding: "test", primaryShard: s.shard1.shardName}));
|
|
|
|
var db = s.getDB("test");
|
|
let primary = s.getPrimaryShard("test").getDB("test");
|
|
let secondary = s.getOther(primary).getDB("test");
|
|
|
|
let curT;
|
|
|
|
function makeObjectDotted(v) {
|
|
let o = {};
|
|
if (curT.compound) {
|
|
let prefix = curT.keyfield + ".";
|
|
if (typeof v == "object") {
|
|
for (var key in v) o[prefix + key] = v[key];
|
|
} else {
|
|
for (var key in curT.values[0]) o[prefix + key] = v;
|
|
}
|
|
} else {
|
|
o[curT.keyfield] = v;
|
|
}
|
|
return o;
|
|
}
|
|
|
|
function makeObject(v) {
|
|
let o = {};
|
|
let p = o;
|
|
|
|
let keys = curT.keyfield.split(".");
|
|
for (var i = 0; i < keys.length - 1; i++) {
|
|
p[keys[i]] = {};
|
|
p = p[keys[i]];
|
|
}
|
|
|
|
p[keys[i]] = v;
|
|
|
|
return o;
|
|
}
|
|
|
|
function makeInQuery() {
|
|
if (curT.compound) {
|
|
// cheating a bit...
|
|
return {"o.a": {$in: [1, 2]}};
|
|
} else {
|
|
return makeObjectDotted({$in: curT.values});
|
|
}
|
|
}
|
|
|
|
function getKey(o) {
|
|
let keys = curT.keyfield.split(".");
|
|
for (let i = 0; i < keys.length; i++) {
|
|
o = o[keys[i]];
|
|
}
|
|
return o;
|
|
}
|
|
|
|
Random.setRandomSeed();
|
|
|
|
for (let i = 0; i < types.length; i++) {
|
|
curT = types[i];
|
|
|
|
print("\n\n#### Now Testing " + curT.name + " ####\n\n");
|
|
|
|
let shortName = "foo_" + curT.name;
|
|
let longName = "test." + shortName;
|
|
|
|
let c = db[shortName];
|
|
s.adminCommand({shardcollection: longName, key: makeObjectDotted(1)});
|
|
|
|
assert.eq(1, findChunksUtil.findChunksByNs(s.config, longName).count(), curT.name + " sanity check A");
|
|
|
|
let unsorted = Array.shuffle(Object.extend([], curT.values));
|
|
c.insert(makeObject(unsorted[0]));
|
|
for (let x = 1; x < unsorted.length; x++) {
|
|
c.save(makeObject(unsorted[x]));
|
|
}
|
|
|
|
assert.eq(6, c.find().count(), curT.name + " basic count");
|
|
|
|
s.adminCommand({split: longName, middle: makeObjectDotted(curT.values[0])});
|
|
s.adminCommand({split: longName, middle: makeObjectDotted(curT.values[2])});
|
|
s.adminCommand({split: longName, middle: makeObjectDotted(curT.values[5])});
|
|
|
|
s.adminCommand({
|
|
movechunk: longName,
|
|
find: makeObjectDotted(curT.values[2]),
|
|
to: secondary.getMongo().name,
|
|
_waitForDelete: true,
|
|
});
|
|
|
|
s.printChunks();
|
|
|
|
assert.eq(3, primary[shortName].find().toArray().length, curT.name + " primary count");
|
|
assert.eq(3, secondary[shortName].find().toArray().length, curT.name + " secondary count");
|
|
|
|
assert.eq(6, c.find().toArray().length, curT.name + " total count");
|
|
assert.eq(6, c.find().sort(makeObjectDotted(1)).toArray().length, curT.name + " total count sorted");
|
|
|
|
assert.eq(6, c.find().sort(makeObjectDotted(1)).count(), curT.name + " total count with count()");
|
|
|
|
assert.eq(
|
|
2,
|
|
c.find({$or: [makeObjectDotted(curT.values[2]), makeObjectDotted(curT.values[4])]}).count(),
|
|
curT.name + " $or count()",
|
|
);
|
|
assert.eq(
|
|
2,
|
|
c
|
|
.find({
|
|
$or: [makeObjectDotted(curT.values[2]), makeObjectDotted(curT.values[4])],
|
|
})
|
|
.itcount(),
|
|
curT.name + " $or itcount()",
|
|
);
|
|
assert.eq(
|
|
4,
|
|
c
|
|
.find({
|
|
$nor: [makeObjectDotted(curT.values[2]), makeObjectDotted(curT.values[4])],
|
|
})
|
|
.count(),
|
|
curT.name + " $nor count()",
|
|
);
|
|
assert.eq(
|
|
4,
|
|
c
|
|
.find({
|
|
$nor: [makeObjectDotted(curT.values[2]), makeObjectDotted(curT.values[4])],
|
|
})
|
|
.itcount(),
|
|
curT.name + " $nor itcount()",
|
|
);
|
|
|
|
let stats = c.stats();
|
|
printjson(stats);
|
|
assert.eq(6, stats.count, curT.name + " total count with stats()");
|
|
|
|
let count = 0;
|
|
for (let shard in stats.shards) {
|
|
count += stats.shards[shard].count;
|
|
}
|
|
assert.eq(6, count, curT.name + " total count with stats() sum");
|
|
|
|
assert.eq(curT.values, c.find().sort(makeObjectDotted(1)).toArray().map(getKey), curT.name + " sort 1");
|
|
assert.eq(
|
|
curT.values,
|
|
c.find(makeInQuery()).sort(makeObjectDotted(1)).toArray().map(getKey),
|
|
curT.name + " sort 1 - $in",
|
|
);
|
|
assert.eq(curT.values.reverse(), c.find().sort(makeObjectDotted(-1)).toArray().map(getKey), curT.name + " sort 2");
|
|
|
|
assert.eq(0, c.find({xx: 17}).sort({zz: 1}).count(), curT.name + " xx 0a ");
|
|
assert.eq(0, c.find({xx: 17}).sort(makeObjectDotted(1)).count(), curT.name + " xx 0b ");
|
|
assert.eq(0, c.find({xx: 17}).count(), curT.name + " xx 0c ");
|
|
assert.eq(0, c.find({xx: {$exists: true}}).count(), curT.name + " xx 1 ");
|
|
|
|
c.update(makeObjectDotted(curT.values[3]), {$set: {xx: 17}});
|
|
assert.eq(1, c.find({xx: {$exists: true}}).count(), curT.name + " xx 2 ");
|
|
assert.eq(curT.values[3], getKey(c.findOne({xx: 17})), curT.name + " xx 3 ");
|
|
|
|
assert.commandWorked(c.update(makeObjectDotted(curT.values[3]), {$set: {xx: 17}}, {upsert: true}));
|
|
|
|
assert.commandWorked(c.createIndex({_id: 1}));
|
|
|
|
// multi update
|
|
var mysum = 0;
|
|
c.find().forEach(function (z) {
|
|
mysum += z.xx || 0;
|
|
});
|
|
assert.eq(17, mysum, curT.name + " multi update pre");
|
|
|
|
c.update({}, {$inc: {xx: 1}}, false, true);
|
|
|
|
var mysum = 0;
|
|
c.find().forEach(function (z) {
|
|
mysum += z.xx || 0;
|
|
});
|
|
assert.eq(23, mysum, curT.name + " multi update");
|
|
}
|
|
|
|
s.stop();
|