karmaker
karmaker

Reputation: 201

SpringData mongoDB API for Aggregation $map

Following is my Native MongoDB query and below is the SpringData Mongo API equivalent. I am getting struck on using $map in $project in SpringData Mongo API. Appreciate your help on completing my conversion to API

db.users.aggregate([    
    { $match: {$and : [{userType:"200"} },    
     { $unwind: "$userOrgMap" },
    {
      $lookup:
        {
          from: "users",
          localField: "userOrgMap.createdbyuser",
          foreignField: "_id",
          as: "created_by"
        }
   },
   {$project:{
       _id:"$_id",
       login:"$login",
       firstName:"$firstName",
       lastName:"$lastName",
       email:"$email",
       deactivateFlag:"$deactivateFlag",
       createdOn:"$createdOn",
       createdBy:{
        "$map": { 
                    "input": "$created_by", 
                    "as": "u", 
                      "in": { 
                          "name": { "$concat" : [ "$$u.firstName", " ", "$$u.lastName" ] }, 
                      } 
                }
    }
      }
    },
    { $sort : { createdBy : 1} }

])

Spring Query

 Aggregation aggregation = newAggregation(
            Aggregation.match(Criteria.where("userType").is(userType)),
            Aggregation.unwind("userOrgMap"),
            Aggregation.lookup("users", "userOrgMap.createdbyuser", "_id", "created_by"),
            Aggregation.project("userId","login","firstName","lastName","email","deactivateFlag","createdOn")
        );

Upvotes: 0

Views: 4385

Answers (2)

Divya Gopal
Divya Gopal

Reputation: 129

This is another approach I was able to do this.

Aggregation.project("userId","login","firstName","lastName","email","deactivateFlag","createdOn").and(VariableOperators.Map.itemsOf("created_by").as("u").andApply(StringOperators.Concat.valueOf("$$u.firstName").concat(" ").concatValueOf("$$u.lastName"))).as("createdBy");

Upvotes: 2

s7vr
s7vr

Reputation: 75934

You can try below $map aggregation.

  project().and(mapItemsOf("created_by").
                            as("u").
                            andApply(new AggregationExpression() {
                                @Override
                                public DBObject toDbObject(AggregationOperationContext aggregationOperationContext) {
                                    return new BasicDBObject("name", StringOperators.valueOf("u.firstName").concat(" ").concatValueOf("u.lastName").toDbObject(aggregationOperationContext));
                                }
                            }))
             .as("createdBy");

Using $let expression

 project().and(VariableOperators.Let.define(VariableOperators.Let.ExpressionVariable.newVariable("u").forExpression(ArrayOperators.arrayOf("created_by").elementAt(0))).
                            andApply(new AggregationExpression() {
                                @Override
                                public DBObject toDbObject(AggregationOperationContext aggregationOperationContext) {
                                    return new BasicDBObject("name", StringOperators.valueOf("u.firstName").concat(" ").concatValueOf("u.lastName").toDbObject(aggregationOperationContext));
                                }
                            }))
            .as("createdBy");

Use lambda and static imports.

import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.arrayOf;
import static org.springframework.data.mongodb.core.aggregation.StringOperators.valueOf;
import static org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable.*;
import static org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.define;
import static org.springframework.data.mongodb.core.aggregation.VariableOperators.mapItemsOf;

project().and(mapItemsOf("created_by").
                as("u").
                andApply(aggregationOperationContext -> new BasicDBObject("name", valueOf("u.firstName").concat(" ").concatValueOf("u.lastName").toDbObject(aggregationOperationContext))))
                .as("createdBy");

    project().and(define(newVariable("u").forExpression(arrayOf("created_by").elementAt(0))).
            andApply(aggregationOperationContext -> new BasicDBObject("name", valueOf("u.firstName").concat(" ").concatValueOf("u.lastName").toDbObject(aggregationOperationContext))))
            .as("createdBy");

Upvotes: 3

Related Questions