opax
opax

Reputation: 139

Spring Data MongoDB collection aggregation

I have some objects in MongoDB document, like this:

{
    "_id" : ObjectId("0"),
    "project" : "PRO",
    "recruiters" : [ 
        {
            "userId" : "User1",
            "fullName" : "UserName1"
        }
    ],
}

{
    "_id" : ObjectId("1"),
    "project" : "PRO2",
    "recruiters" : [ 
        {
            "userId" : "User1",
            "fullName" : "UserName1"
        }
    ],
}

{
    "_id" : ObjectId("1"),
    "project" : "PRO2",
    "recruiters" : [ 
        {
            "userId" : "User1",
            "fullName" : "UserName2"
        }
    ],

How can I aggregate that document in Spring Data to result like this:

{  
   "Agg":[  
      {  
         "fullName":"UserName1",
         "total":2
      },
      {  
         "fullName":"UserName2",
         "total":1
      }
   ]
}

I tried to do it some like this:

Aggregation agg = newAggregation(
        match(Criteria.where("project").is("project")),
        group("recruiters").count().as("total"),
        project("total").and("fullName").previousOperation(),
        sort(Sort.Direction.DESC, "total"));

but I can't do it on collections. I want to group all fullName of "recruiters" in whole document and show them count.

Upvotes: 1

Views: 1519

Answers (3)

s7vr
s7vr

Reputation: 75934

Use $unwind to convert the array into documents.

Aggregation agg = newAggregation(
   match(Criteria.where("project").is(project)),
   unwind("recruiters"),
   group("recruiters.fullName").count().as("total"),
   project("total").and("fullName").previousOperation(),
   sort(Sort.Direction.DESC, "total")
);

Upvotes: 2

gajju_15
gajju_15

Reputation: 527

Try this:- with unwind()

Aggregation agg = newAggregation(
        match(Criteria.where("project").exists(true)),//if project field exist in document
    unwind("recruiters"), // unwind the array of object
        group("recruiters.fullName").count().as("total"),
        project("total").and("fullName").previousOperation(),
        sort(Sort.Direction.DESC, "total"));

Upvotes: 1

pvpkiran
pvpkiran

Reputation: 27048

Try this

MatchOperation matchOperation = Aggregation.match(Criteria.where("project").is("PRO"));
GroupOperation groupOperation = group("recruiters.fullName").count().as("total");
ProjectionOperation projectionOperation = project("total").and("fullName").previousOperation();

SortOperation sortOperation = sort(Sort.Direction.DESC, "total");
Aggregation aggregation = newAggregation(matchOperation, groupOperation, projectionOperation,  sortOperation);
AggregationResults<DBObject> results = mongoTemplate.aggregate(aggregation, "YourCollectionName", DBObject.class);

Instead of DBObject you can create a class mathcing the result and use that.

Upvotes: 0

Related Questions