1

I have an project using Hibernate. This has a class named Question. Each Question has a difficulty level (1,2,3); Each Question also has an attribute is field (a,b,c,d,e,f,g,h,i,k);

Suppose I have 100 questions. I want to get randomly 20 question with conditions:

  • 7 questions in level 1
  • 7 questions in level 2
  • 6 questions in level 3.
  • Each field have at least 1 question

Thanks to all ^^

Chris J
  • 30,688
  • 6
  • 69
  • 111

1 Answers1

1

First of all, I think this problem is too difficult to be solved by using a Hibernate query, or even a set of Hibernate queries.

Here's how I would do:

  • load all 100 questions in memory
  • create a Map<Field, List<Question>>, and shuffle all the lists in this map
  • for each field, take the first question of the corresponding list that has an acceptable level
  • Once you have one question in every field, take all the remaining questions, put them in a list, shuffle the list, and iterate over the list. Each time a question has a level which is acceptable, take it. Do that until you have your 20 questions.

This should work if, for each field, you're guaranteed to have at least a question for every level. If it's not the case, then it's more difficult.

If you have much more questions that 100, and they can't be loaded in memory, you could use the same kind of algorithm, but use random queries to select the questions:

  • issue one query per field to find a question in each field. The where clause should only accept the given field, and should only accept the levels which are still acceptable.
  • issue a query to find N questions randomly (with N being equal to 50, for example, and with a where clause which only accepts the remaining levels), and take the first 10 acceptable questions. If there are less than 10 acceptable questions, try again. There should be at most 3 such queries. Make sure your where clause rejects the IDs of the questions which have already been loaded.
Community
  • 1
  • 1
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • i think we can remove the selected questions in step 3 from the collection so we don't have to re-shuffle the collection in step 4; and what if there are not only 100 questions and we cannot load all of them in memory? – user1151484 Jan 16 '12 at 10:01
  • The point of step 4 is to put all the remaining questions, whatever their field is, in the same list. If you don't shuffle this list, you'll find all the questions of a given field grouped together. I'll edit my question regarding the last point. – JB Nizet Jan 16 '12 at 10:07