Spring Boot, MongoDB, Pageable, сортировка по пользовательскому методу в объекте - PullRequest
0 голосов
/ 22 апреля 2020

Скажем, например, у меня есть следующие настройки,

Модель, подобная этой:

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();
    }
}

и

public class Vote {

    private short direction;

    // Getters & Setters...
}

, а затем такой репозиторий

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

    List<Post> findAll(Pageable pageable);
}

И, скажем, я хочу отсортировать сообщения по результату метода get getUpVotes()

Я пробовал следующее localhost:3005/opinion?page=0&size=20&sort=upVotes, но оно не работает.

1 Ответ

0 голосов
/ 22 апреля 2020

В документе сортировки можно указать сортировку по возрастанию или убыванию в существующих полях ...

https://docs.mongodb.com/manual/reference/method/cursor.sort/#sort -as c -des c

Обходной путь : Вы можете выполнить Агрегирование MongoDB , где вы можете добавить новое поле с вычисленным значением и порядком по этому значению:

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

MongoPlayground | $project

Данные пружины

@Autowired
private MongoTemplate mongoTemplate;
...

Aggregation aggregation = Aggregation.newAggregation(addFields, sort);
List<Post> result = mongoTemplate
                       .aggregate(aggregation, mongoTemplate.getCollectionName(Post.class), Post.class)
                       .getMappedResults();
...