0

Say for example I have the following setup,

A model like this:

public class Post {

    @Id
    private String id;
    private String post;
    private List<Vote> votes = new ArrayList<>();

    // Getters & Setters...
    public double getUpVotes() {
        return votes.stream().filter(vote -> vote.getDirection() == 1).mapToInt(Vote::getDirection).count();
    }
}

and

public class Vote {

    private short direction;

    // Getters & Setters...
}

and then a repository like this

@Repository
public interface PostRepository extends PagingAndSortingRepository<Post, String> {

    List<Post> findAll(Pageable pageable);
}

And say I want to sort the posts by the result of the getter method getUpVotes()

I've tried the following localhost:3005/opinion?page=0&size=20&sort=upVotes but its doesn't work.

Darragh O'Flaherty
  • 995
  • 3
  • 13
  • 30

1 Answers1

0

The sort document can specify ascending or descending sort on existing fields ...

https://docs.mongodb.com/manual/reference/method/cursor.sort/#sort-asc-desc

Workaround: You can perform MongoDB aggregation where you can add new field with calculated value and order by this value:

db.post.aggregate([
  {
    $addFields: {
      upVotes: {
        $size: {
          $filter: {
            input: "$votes.direction",
            cond: {
              $eq: [ "$$this", 1 ]
            }
          }
        }
      }
    }
  },
  {
    $sort: {
      upVotes: 1
    }
  }
])

MongoPlayground | $project

Spring data

@Autowired
private MongoTemplate mongoTemplate;
...

Aggregation aggregation = Aggregation.newAggregation(addFields, sort);
List<Post> result = mongoTemplate
                       .aggregate(aggregation, mongoTemplate.getCollectionName(Post.class), Post.class)
                       .getMappedResults();
Community
  • 1
  • 1
Valijon
  • 12,667
  • 4
  • 34
  • 67