Javascript function does not produce any output

This topic comes from Using $function to run a javascript function is not working in mongosh - #2 by Jason_Tran

I need to use a javascript function inside an aggregation, so I started from basic aggregation, like “Hello” functions (reference: How to Use Custom Aggregation Expressions in MongoDB 4.4 | MongoDB)
In previous topic I learnt that I need to use standalone shell, not compass shell, to run these kind of aggregations (If I use Compass shell, the code hangs and the prompt is not returned). I have 2 sintaxes for this simple code, but they don’t produce any output. Do I need to install anything else so these codes work?

db.movies.aggregate([
    { 
      $addFields: {
        fromFunction: {
          $function: {
            body: "function(){return 'hello'}",
            args: [], 
            lang: 'js'
          }
        }
       }
     }
  ])

  1. use test - Switch to "test" database
  2. db.movies.insertOne({a:1}) - Insert a sample / test document into the "movies" collection
db.movies.aggregate([
  {
    '$addFields': {
      fromFunction: { '$function': { body: function(){return 'hello'}, args: [], lang: 'js' } }
    }
  }
])

Hi @Luis_Leon

I tried the exact code you posted and got the expected output:

> db.version()
6.0.6

> db.test.find()
[ { _id: 0 } ]

> db.test.aggregate([
...     {
...       $addFields: {
...         fromFunction: {
...           $function: {
...             body: "function(){return 'hello'}",
...             args: [],
...             lang: 'js'
...           }
...         }
...        }
...      }
...   ])
[ { _id: 0, fromFunction: 'hello' } ]

I literally just copy pasted the first example you have. With regards to your second example, the function(){...} is unquoted. Perhaps this is the issue?

Having said that, note that using $function will be a lot less performant compared to using built-in aggregation pipelines. It’s recommended for you to do this if your needs cannot be satisified otherwise.

Best regards
Kevin

1 Like

Hi @kevinadi Thanks for your reply. Did you do anything else in your mongo installation in order to run a function? I tried again, I’m using the exact mongo version but I’m not getting an output like yours. Anyway, you mentioned that a built-in aggregation pipeline has better performance. The reason why I’m trying to use a function is parsing a json string, I haven’t find any other way to parse that kind of data field without using a function. Can you think an alternative way to do it?

Hi @Luis_Leon

No I didn’t do anything special. It’s just a plain vanilla MongoDB 6.0.6 single-node replica set deployment that I use locally for testing purposes. However, it shouldn’t matter if it’s a standalone node, a replica set, or even a sharded cluster.

However if you’re using Atlas shared tier (M0/M2/M5) then server-side Javascript is not supported (see Atlas M0 (Free Cluster), M2, and M5 Limitations). Otherwise you’ll see an error like MongoServerError: $function not allowed in this atlas tier

Can you show us an example document, and how the output should look like?

Best regards
Kevin

Sure. Look at this link, it uses real data I’m working with. I don’t know why it works in this mongo playground but is not working in my environment (I didn’t create this link but some guy in stackoverflow):

Hi @Luis_Leon

Thanks for providing the example.

I see that the javascript function executed is:

function(jsonString){return JSON.parse(jsonString)}

basically it just parses a JSON document that was stored as a string, and dump the parsed document in the output, creating a sub-document.

Wouldn’t this be better if the JSON string is stored as an actual sub-document in MongoDB? After all, this is what MongoDB is good at. Depending on your case, maybe you can pre-process the raw workflowParams string during document insertion, so you don’t need to use $function in the query.

Also, I copy pasted the example document and the query, and the output I get is identical to the MongoPlayground output.

Best regards
Kevin

3 Likes

Thanks Kevin, that’s a good observation, I don’t know if the customer is willing to pre-process the raw string, but maybe is the only solution to this problem for now, as I checked and noticed that they have mongo 4.0.0, and apparently $function is not supported in that mongodb version (my local installation is Mongo 6.0.6).

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.