silentsudo
silentsudo

Reputation: 6973

Project ObjectId to String in spring data mongo

Hi Following are my documents "users"

{
    "_id" : ObjectId("5dcab69fc6355e16d8164bd3"),
    "username" : "kellen.swift",
    "firstName" : "Kellen",
    "lastName" : "Swift",
    "authorities" : [],
    "active" : true,
    "_class" : "...User"
}

"comments"

{
    "_id" : ObjectId("5dcac8fc75de953b5c3025cb"),
    "content" : "Wonderful, thanks for the explanation",
    "videoId" : "5dcab83475de951cc80dd2f0",
    "userId" : "5dcab69fc6355e16d8164bd3",
    "active" : true,
    "_class" : "...Comment"
}

I am composing UserComments using following query:

db.users.aggregate([
        {
            "$project": {
                "_id": {
                    "$toString": "$_id"
                },
                "username": 1,
                "firstName": 1,
                "lastName": 1,
            }
        },
        {
            $lookup: {
                    from: "comments",
                    localField: "_id",
                    foreignField: "userId",
                    as: "user_comments"
            }
        },
        {
            $unwind: "$user_comments"
        },
        {
            $project:{
                username: 1,
                name: {
                    $concat: ["$firstName", " ", "$lastName"]
                },
                content: "$user_comments.content",
                videoId: "$user_comments.videoId"
            }
        }
]);

This Gives me a proper result using Robo3t.

When I try to execute the same command from the spring data interface, I am not able to get the exact result.

Following is my java code:

private void getAllUserCommentsForVideo(String userId) {

        ProjectionOperation userProjections = Aggregation.project().andInclude("username", "firstName", "lastName");


        LookupOperation lookup = Aggregation.lookup(
                "comments",
                "_id",
                "userId",
                "userComments"
        );

        ProjectionOperation userCommentProject = Aggregation.project(
                "username"
        ).andInclude("userComments.content");

        Aggregation aggregation = Aggregation.newAggregation(
                userProjections,
                lookup,
                Aggregation.unwind("userComments"),
                userCommentProject
        );

        List<BasicDBObject> users = mongoTemplate.aggregate(aggregation, "users", BasicDBObject.class).getMappedResults();
        for (BasicDBObject object : users) {
            System.out.println(object.toJson());
        }

    }

From Query, I can see that _id is not mapped properly, am I doing something wrong here.

Please let me know any modification required to execute this successfully.

Thank you.

Upvotes: 2

Views: 1292

Answers (1)

Igor H
Igor H

Reputation: 156

Try to create custom aggregation operation to properly map ObjectId to string:

AggregationOperation projectionOperation = context -> {
    Document toString = new Document("$toString", "$_id");
    Document id = new Document("_id", toString);
    Document project = new Document("$project", id);

    return project;
};

Upvotes: 2

Related Questions