82 lines
2.4 KiB
JavaScript
82 lines
2.4 KiB
JavaScript
/**
|
|
* $replaceRoot can be used to extract parts of a document; here we test a simple address case.
|
|
*/
|
|
|
|
import {arrayEq} from "jstests/aggregation/extras/utils.js";
|
|
|
|
Random.setRandomSeed();
|
|
|
|
/**
|
|
* Helper to get a random entry out of an array.
|
|
*/
|
|
function randomChoice(array) {
|
|
return array[Random.randInt(array.length)];
|
|
}
|
|
|
|
/**
|
|
* Helper to generate a randomized document with the following schema:
|
|
* {
|
|
* name: <string>,
|
|
* address: {number: <3-digit int>, street: <string>, city: <string>, zip: <5-digit int>}
|
|
* }
|
|
*/
|
|
function generateRandomDocument() {
|
|
let names = ["Asya", "Charlie", "Dan", "Geert", "Kyle"];
|
|
const minNumber = 1;
|
|
const maxNumber = 999;
|
|
let streets = ["3rd", "4th", "5th", "6th", "7th", "8th", "9th"];
|
|
let cities = ["New York", "Palo Alto", "Sydney", "Dublin"];
|
|
const minZip = 10000;
|
|
const maxZip = 99999;
|
|
|
|
return {
|
|
names: randomChoice(names),
|
|
address: {
|
|
number: Random.randInt(maxNumber - minNumber + 1) + minNumber,
|
|
street: randomChoice(streets),
|
|
city: randomChoice(cities),
|
|
zip: Random.randInt(maxZip - minZip + 1) + minZip,
|
|
},
|
|
};
|
|
}
|
|
|
|
const collName = jsTest.name();
|
|
const coll = db.getCollection(collName);
|
|
coll.drop();
|
|
|
|
// Insert a bunch of documents of the form above.
|
|
const nDocs = 10;
|
|
let bulk = coll.initializeUnorderedBulkOp();
|
|
for (let i = 0; i < nDocs; i++) {
|
|
bulk.insert(generateRandomDocument());
|
|
}
|
|
assert.commandWorked(bulk.execute());
|
|
|
|
// Extract the contents of the address field, and make sure that doing the same
|
|
// with replaceRoot yields the correct answer.
|
|
// First compute each separately, since we know all of the fields in the address,
|
|
// to make sure we have the correct results.
|
|
let addressPipe = [
|
|
{
|
|
$project: {
|
|
"_id": 0,
|
|
"number": "$address.number",
|
|
"street": "$address.street",
|
|
"city": "$address.city",
|
|
"zip": "$address.zip",
|
|
},
|
|
},
|
|
];
|
|
let correctAddresses = coll.aggregate(addressPipe).toArray();
|
|
|
|
// Then compute the same results using $replaceRoot.
|
|
let replaceWithResult = coll
|
|
.aggregate([{$replaceRoot: {newRoot: "$address"}}, {$sort: {city: 1, zip: 1, street: 1, number: 1}}])
|
|
.toArray();
|
|
|
|
// Then assert they are the same.
|
|
assert(
|
|
arrayEq(replaceWithResult, correctAddresses),
|
|
"$replaceRoot does not work the same as $project-ing the relevant fields to the top level",
|
|
);
|