mirror of https://github.com/mongodb/mongo
112 lines
2.8 KiB
JavaScript
112 lines
2.8 KiB
JavaScript
// Tests basic functionality of the $_internalJsEmit expression, which provides capability for the
|
|
// map stage of MapReduce.
|
|
//
|
|
// @tags: [
|
|
// requires_scripting,
|
|
// ]
|
|
import {resultsEq} from "jstests/aggregation/extras/utils.js";
|
|
|
|
const coll = db.js_emit_expr;
|
|
coll.drop();
|
|
|
|
function fmap() {
|
|
for (let word of this.text.split(" ")) {
|
|
emit(word, 1);
|
|
}
|
|
}
|
|
|
|
let pipeline = [
|
|
{
|
|
$project: {
|
|
emits: {
|
|
$_internalJsEmit: {
|
|
"this": "$$ROOT",
|
|
"eval": fmap,
|
|
},
|
|
},
|
|
_id: 0,
|
|
},
|
|
},
|
|
{$unwind: "$emits"},
|
|
{$replaceRoot: {newRoot: "$emits"}},
|
|
];
|
|
|
|
assert.commandWorked(coll.insert({text: "hello world"}));
|
|
|
|
let results = coll.aggregate(pipeline, {cursor: {batchSize: 1}}).toArray();
|
|
assert(
|
|
resultsEq(results, [
|
|
{k: "hello", v: 1},
|
|
{k: "world", v: 1},
|
|
]),
|
|
results,
|
|
);
|
|
|
|
assert.commandWorked(coll.insert({text: "mongo db"}));
|
|
|
|
// Set batchSize to 1 to check that the expression is able to run across getMore's.
|
|
results = coll.aggregate(pipeline, {cursor: {batchSize: 1}}).toArray();
|
|
assert(
|
|
resultsEq(results, [
|
|
{k: "hello", v: 1},
|
|
{k: "world", v: 1},
|
|
{k: "mongo", v: 1},
|
|
{k: "db", v: 1},
|
|
]),
|
|
results,
|
|
);
|
|
|
|
// Test that the 'eval' function accepts a string argument.
|
|
pipeline[0].$project.emits.$_internalJsEmit.eval = fmap.toString();
|
|
results = coll.aggregate(pipeline, {cursor: {batchSize: 1}}).toArray();
|
|
assert(
|
|
resultsEq(results, [
|
|
{k: "hello", v: 1},
|
|
{k: "world", v: 1},
|
|
{k: "mongo", v: 1},
|
|
{k: "db", v: 1},
|
|
]),
|
|
results,
|
|
);
|
|
|
|
// Test that the command correctly fails for an invalid operation within the JS function.
|
|
assert.commandWorked(coll.insert({text: 5}));
|
|
assert.commandFailedWithCode(
|
|
db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}),
|
|
ErrorCodes.JSInterpreterFailure,
|
|
);
|
|
|
|
// Test that the command correctly fails for invalid arguments.
|
|
pipeline = [
|
|
{
|
|
$project: {
|
|
emits: {
|
|
$_internalJsEmit: {
|
|
"this": "must evaluate to an object",
|
|
"eval": fmap,
|
|
},
|
|
},
|
|
_id: 0,
|
|
},
|
|
},
|
|
];
|
|
assert.commandFailedWithCode(db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}), 31225);
|
|
|
|
pipeline = [
|
|
{
|
|
$project: {
|
|
emits: {
|
|
$_internalJsEmit: {
|
|
"this": "$$ROOT",
|
|
"eval": "this is not a valid function!",
|
|
},
|
|
},
|
|
_id: 0,
|
|
},
|
|
},
|
|
];
|
|
assert.commandFailedWithCode(
|
|
db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}),
|
|
ErrorCodes.JSInterpreterFailure,
|
|
);
|