2

I wrote the following aggregation pipeline that returns the most liked items in my users collection

db.users.aggregate([
  {$unwind: "$favoriteItems"},
  {$group: {
    _id: "$favoriteItems" ,
    likes: { $sum: 1 }
  }},
  {$sort: { likes: -1 }}
])

Here is a prototype document from my users collection:

{
  "_id": "5a6df13552f42a34dcca9aa6",
  "username": "user1",
  "favoriteItems": [
    {
      "_id": "5a0c6b2dfd3eb67969316d6d",
      "name": "item1"
    },
    {
      "_id": "5a0c680afd3eb67969316d0b",
      "name": "item2"
    }
  ]
}

This is my attempt at doing the same in java:

public void getMostLikedItems () {
        UnwindOperation unwind = Aggregation.unwind("favoriteItems");
        GroupOperation group = Aggregation.group("favoriteItems").sum("1").as("likes");
        SortOperation sort = Aggregation.sort(Sort.Direction.DESC, "likes");

        Aggregation aggregation = newAggregation(unwind, group, sort);
        AggregationResults<LikedItem > result = mongoTemplate.aggregate(aggregation, "users", LikedItem .class);
        for (LikedItem s: result) {
            System.out.println(s.getId() + ": " + s.getValue());
        }
    }

This is not yielding any output. What am i missing here?

EDIT LikedItem.java

public class LikedItem {

    private Item id;
    private float value;
    // empty and full constructor + getters and setters

}

EDIT 2 Item class

public class Item{
    @Id
    private String id;
    private String name;
    private String city;
    @GeoSpatialIndexed(type= GeoSpatialIndexType.GEO_2DSPHERE)
    private GeoJsonPoint location;

    public Shop() { super(); }
    // full constructor + getters and setters
}
6
  • have you checked logs, what query has been fired? Commented Jan 28, 2018 at 17:24
  • @Saravana I see nothing in IDE console nor the mongod.exe log. Is there anywhere else I should check? Commented Jan 28, 2018 at 17:31
  • Its likely you're getting some output but it is not mapped. Can you add LikedItem to the post ? Try Document result = mongoTemplate.aggregate(aggregation, "users", LikedItem.class).getRawResults(); to view what you get back from mongo Commented Jan 28, 2018 at 17:33
  • @Veeram, I editted my post to include LikedItem class. Commented Jan 28, 2018 at 18:00
  • Did you try my suggestion ? Please also include item class. Commented Jan 28, 2018 at 18:02

1 Answer 1

2

You're using the incorrect method.

sum method takes reference and you get something like "likes" : { "$sum" : "$1" }.

Use count method instead to output "likes" : { "$sum" : 1 }

GroupOperation group = Aggregation.group("favoriteItems").count().as("likes");
Sign up to request clarification or add additional context in comments.

2 Comments

thank you for pointing the function error. Right now I am getting an exception: com.mongodb.MongoCommandException: Command failed with error 9: 'The 'cursor' option is required, except for aggregate with the explain argument' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "The 'cursor' option is required, except for aggregate with the explain argument", "code" : 9, "codeName" : "FailedToParse" }
Also, my rest controller returns a description of the error which includes Command = { "aggregate" : "users" , "pipeline" : [ { "$unwind" : "$preferredShops"} , { "$group" : { "_id" : "$preferredShops" , "likes" : { "$sum" : 1}}} , { "$sort" : { "likes" : -1}}]}; nested exception is com.mongodb.MongoCommandException:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.