Home > OS >  Call a Mongo function from aggregation pipeline through JAVA Driver API
Call a Mongo function from aggregation pipeline through JAVA Driver API

Time:01-07

I am able to get the following working in mongosh

var pipeline = [
    { $group: { _id: "$column1", valArray: { $push: "$column2" } } },
    { $set: {
            val: function1("$valArray", 70)    
        }
    },
    { $unset: [ "valArray" ] },
    { $sort: { _id: 1 } }
];

function1 is function defined to take an array and a number as param

When I try the same with Java I get the error while trying to create List

List<Bson> pipeline = Stream.of(new String[] {
    "{ $group: { _id: \"$column1\", valArray: { $push: \"$column2\" } } }",
    "{ $set: { percentile_n: function1(\"$valArray\", "   percentileN   ") } }",
    "{ $unset: [ \"valArray\" ] }",
    "{ $sort: { _id: 1 } }"
  })
  .map(s -> Document.parse(s).toBsonDocument())
  .collect(Collectors.toList());


Exception in thread "main" org.bson.json.JsonParseException: **JSON reader was expecting a value but found 'function1'**.
    at org.bson.json.JsonReader.readBsonType(JsonReader.java:263)
    at org.bson.codecs.DocumentCodec.decode(DocumentCodec.java:175)
    at org.bson.codecs.DocumentCodec.decode(DocumentCodec.java:44)
    at org.bson.internal.LazyCodec.decode(LazyCodec.java:48)
    at org.bson.codecs.ContainerCodecHelper.readValue(ContainerCodecHelper.java:61)
    at org.bson.codecs.DocumentCodec.decode(DocumentCodec.java:177)
    at org.bson.codecs.DocumentCodec.decode(DocumentCodec.java:44)
    at org.bson.Document.parse(Document.java:126)
    at org.bson.Document.parse(Document.java:111)

Looks like there is a specific way to create BsonDocument for a function call. Can anyone please help?

CodePudding user response:

Seems like Mongo does not facilitate execution of functions on server from API. Only through mongo shell is this allowed.

CodePudding user response:

I would suggest you use $function. You can find some references in the documentation.

I just tried the following over a sample dataset and it works.

db.getCollection('projects').aggregate([ 
  { $group: { _id: "$status", count: { $count: {} }, packages: { $push: "$packageSlip" } } }, 
  { $set: { val: { $function: { 
      body: function(currentDaysLeft, extraDays){ return currentDaysLeft   extraDays}, 
      args: ['$daysLeft', 70], 
      lang: "js" } } } }
])

Good Luck

  •  Tags:  
  • Related