skip to Main Content

I was wondering if was possible to utilize functions inside of MongoDB query by including a function inside of options block or something.

Suppose my database collection has a document:

{"year": "2320"}

And I have function to format this document’s year-field:

const reformat = function(input){
 return input.year.substring(2,4)+input.year.substring(0,2)
}

And I’ll be calling a fetch function like this:

const test = {"year": "2023"}
fetchSomething(test, {}, reformat)

My fetch function looks like this:

async function fetchSomething(query, projection, options){
  const dat = await mongoCli.db("testDB").collection("testCollection").findOne(query, projection, options);
  return dat;
}

So, reformat-function should modify the database’s document to match year-attribute of test-variable, not the other way around.

I’m not sure if MongoDB even supports it. Looking at the MongoDB documentation…

2

Answers


  1. Chosen as BEST ANSWER

    I now realize is that I can accomplish it with a cursor:

    const reformat = function(input){
     return input.year.substring(2,4)+input.year.substring(0,2)
    }
    
    async function fetchSomething(query, options){
      const cursor = await mongoCli.db("testDB").collection("testCollection").find()
      let doc;
      while (await cursor.hasNext()) {
        doc = await cursor.next();
        if (options(doc) == query.year){ break; }
        else { doc = null; }
      }
      cursor.close();
      return doc;
    }
    const test = {"year": "2023"}
    fetchSomething(test, reformat)
    

    Though there might be a better way to do it.


  2. All you could do is like this:

    const reformat = function(){
     return {allowDiskUse: true}
    }
    
    mongoCli.db("testDB").collection("testCollection").findOne(query, projection, reformat()); 
    

    The option is an input attribute of findOne, you cannot re-define it.

    Or you can use $function in aggregation pipeline:

    db.mongoCli.aggregate([
       {
          $set: {
             year: {
                $function: {
                   body: function (input) {
                      return input.year.substring(2, 4) + input.year.substring(0, 2)
                   },
                   args: ["$$ROOT"],
                   lang: "js"
                }
             }
          }
       }
    ])
    

    Please be aware, executing JavaScript inside an aggregation expression may decrease performance. Only use the $function operator if the provided pipeline operators cannot fulfill your application’s needs. $substrCP and $concat are also available as pipeline operator.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search