I am developing a Spring Boot REST API in Kotlin. The underlying db is Postgresql and I am using Spring Data JPA for database access.
I have a table called "Users" , where I have some user data. One of the user properties is "gender". It can have one of two values: MALE or FEMALE.
I would like to have a feature in my app to find a random number (say 20 for example) of people of specified gender that I have not seen before. I mean - let's assume I have a table where I store the ids of users that I have already seen.
So now, what I want to do is basically get 20 random users from Users table, where gender is MALE and id is NOT IN [list of ids I have seen].
The randomness of the query initially led me to creating a native query of the kind:
SELECT * FROM users WHERE gender = :gender ORDER BY random() LIMIT :number
However, I realized that it might be very inefficient, since the order by random() part will be sorting the entire table (or ~half of the table if I select one gender).
So my second idea was to take care of the randomness in the code. So I decided to make a db call to count the amount of users (to fetch the highest id), then generate some id values in the range from 0 to the highest, filter out the ones that I have seen and then fetch the users from DB by ids:
val numberOfUsersInDatabase = userRepository.count()
val idsOfUsersVotedForBefore = voteService.findIdsOfUsersVotedFor(requestingUser.id!!)
val excludedIds = idsOfUsersVotedForBefore.plus(requestingUser.id)
val idsToFetch = random.longs(2*amountOfIds, 1L, numberOfUsersInDatabase)
.boxed()
.filter { num -> !excludedIds.contains(num) }
.limit(amountOfIds)
.collect(toSet())
val randomUsers = userRepository.findUsersByIds(idsToFetch)
But in this case I have no way of knowing what the gender of the randomly selected user is, so there is no possibility for me to filter the results by gender before making the db call.
Can you please advice how to tackle this better?