Home > front end >  How can i run javascript function stored in mongodb document
How can i run javascript function stored in mongodb document

Time:11-13

I'm learning mongodb i have learned how to work will all data types provided by mongo. But I'm stuck at javascript. I have managed to store javascript function in document. But when i was running that function i got nothing out of it.

I'm using mongo shell in terminal.

Script to insert function in mongodb.

db.Test.insertOne({functiontest:function(){return "Hello";}});

After running this command

db.Test.find();

I got this output

{ "_id" : ObjectId("618d4096dc79465b4196551b"), "functiontest" : { "code" : "function(){return \"Hello\";}" } }

After running this command

db.Test.find({functiontest:{$type:"javascript"}},{"functiontest.code":1});

I got this weird output I thought this output will give me function but I got this.

{ "_id" : ObjectId("618d4096dc79465b4196551b") }

I have also tried to run this function with pipeline but that gave me only object Id

db.Test.aggregate([{$match:{functiontest:{$type:"javascript"}}},{$project:{"codeMe":"$functiontest.code()"}}]);

CodePudding user response:

Javascript stored in a user collection is stored as string.

MongoDB internally uses BSON for storage, see https://bsonspec.org/spec.html, which defines the content of the javascript code type as "string":

| "\x0D" e_name string JavaScript code

To demonstrate, I inserted a document into a new collection with:

db.Test.insertOne({_id:"myid",functiontest:function(){return "Hello";}});

The from the bash shell:

% mongodump -d test -c Test
2021-11-12T01:31:33.817-0800    writing test.Test to dump/test/Test.bson
2021-11-12T01:31:33.818-0800    done dumping test.Test (1 document)

% xxd dump/test/Test.bson
00000000: 4100 0000 025f 6964 0005 0000 006d 7969  A...._id.....myi
00000010: 6400 0d66 756e 6374 696f 6e74 6573 7400  d..functiontest.
00000020: 1c00 0000 6675 6e63 7469 6f6e 2829 7b72  ....function(){r
00000030: 6574 7572 6e20 2248 656c 6c6f 223b 7d00  eturn "Hello";}.
00000040: 00 

To break that hex for that second field:

0d - this identifies the javascript code type 

66756e6374696f6e7465737400  null-terminated field name "functiontest"

1c000000 - length = 28 btyrd

66756e6374696f6e28297b72657475726e202248656c6c6f223b7d00 - string 'function(){return "Hello";}'

There is nothing special about that string, other than it is introduced by 0x0d instead of 0x02.

The REPL you are using doesn't actually have a way to display raw BSON, so when you query that document, the driver needs to convert it to some other form. JSON doesn't have a datatype for code (for fun, try running JSON.stringify({fun:function(){}}).

The legacy mongo shell, which uses the C driver, will convert that code type to JSON by putting in an object with the code field name.

The new mongosh shell, which uses the Node.JS driver, will create an instance of the Code class, so the object looks like:

{ _id: 'myid', functiontest: Code("function(){return "Hello";}") }

Which still allows you to access the string with .code:

> db.Test.findOne().functiontest.code
function () {
      return "Hello";
    }

Both of those representations were done by the driver on the client side, so neither one exists on the server, and thus the projection operators can't see them.

Assuming that you are not planning on running your application in the mongo shell, you will probably want to experiment with the driver you actually plan to use to see how this string will be passed back to you.

The bottom line here is the "code" is actually stored as a string, and you will need to use whichever method you prefer for executing string as code.

  • Related