I was hoping someone would have a look at how I retrieve the questions from the db, parse the JSON and process the results - possibly advise how I could improve efficiency by streamlining my code. I feel that the way I have processed the results is rather cumbersome!
I have a MongoDB that is accessed by custom server code. The server deals with matchmaking, rooms, lobbies etc. for multi-player game. The MongoDB is on same space and holds all the questions for the mobile phone quiz game.
This is my first attempt at such a project and although I'm competent in Java and my JSON and Mongo skill are novice.
My result pulls back every questionEntry
element in the documents for a particular TV show that has a metaTag
array element which match the search string.
The query:
// Query our collection documents metaTag elements for a matching string
// @SuppressWarnings("deprecation")
public void queryMetaTags(String query)
{
// Query to search all documents in current collection
List<String> continentList = Arrays.asList(new String[]{query});
DBObject matchFields = new
BasicDBObject("season.questions.questionEntry.metaTags",
new BasicDBObject("$in", continentList));
DBObject groupFields = new BasicDBObject( "_id", "$_id").append("questions",
new BasicDBObject("$push","$season.questions"));
//DBObject unwindshow = new BasicDBObject("$unwind","$show");
DBObject unwindsea = new BasicDBObject("$unwind", "$season");
DBObject unwindepi = new BasicDBObject("$unwind", "$season.questions");
DBObject match = new BasicDBObject("$match", matchFields);
DBObject group = new BasicDBObject("$group", groupFields);
ArrayList<DBObject> pipeline = new ArrayList<>();
pipeline.add(unwindsea);
pipeline.add(unwindepi);
pipeline.add(match);
pipeline.add(group);
@SuppressWarnings("deprecation")
AggregationOutput output =
mongoColl.aggregate(pipeline);
//CommandResult output = (CommandResult)
//mongoColl.aggregate(pipeline,new BasicDBObject("explain",true));
//mongoColl.explainAggregate(unwindsea,unwindepi,match,group);
String jsonString = null;
JSONObject jsonObject = null;
jsonResultsArray = null;
ourResultsArray = new ArrayList<JSONObject>();
// Loop for each document in our collection
for (DBObject result : output.results())
{
try
{
// Parse our results so we can add them to an ArrayList
jsonString = JSON.serialize(result);
jsonObject = new JSONObject(jsonString);
jsonResultsArray = jsonObject.getJSONArray("questions");
// Put each of our returned questionEntry elements into an ArrayList
for (int i = 0; i < jsonResultsArray.length(); i++)
{
//System.out.println("jsonResultsArray element (" + i + "): " + jsonResultsArray.getJSONObject(i).toString());
ourResultsArray.add(jsonResultsArray.getJSONObject(i));
}
}
catch (JSONException e1)
{
e1.printStackTrace();
}
}
}
Each game match consists of 10 questions for this topic, so I pull out a random 10 from the results with:
public void pullOut10Questions()
{
// Array to hold 10 random numbers between 0 and our results total
ArrayList<Integer> ourRandomNumbersList = generate10RandomNumbersInRange(ourResultsArray.size());
// Array to hold our 10 random questions from our results
ourQuestionsArray = new ArrayList<JSONObject>();
// Loop through each of our results in array
for (int i = 0; i < ourResultsArray.size(); i++)
{
// Loop through our array holding our 10 random numbers
for(int j = 0; j < ourRandomNumbersList.size(); j++)
{
// If our results array index equals one of our 10 random numbers
if(ourRandomNumbersList.get(j) == i)
{
// Then add that result to our final questionElement array
ourQuestionsArray.add(ourResultsArray.get(i));
//try { // Remove later it's for print test to console<---------------------------
// System.out.println("Our QuestionEntry from mongo: " + ourResultsArray.get(i).getString("questionEntry"));
//} catch (JSONException e) {
// e.printStackTrace();
//}
}
}
}
}
// Return 10 random numbers in range
public ArrayList<Integer> generate10RandomNumbersInRange(int range)
{
Random rand = new Random();
int e;
int i;
int g = 10;
// Store random numbers is HashSet
HashSet<Integer> randomNumbers = new HashSet<Integer>();
for (i = 0; i < g; i++)
{
e = rand.nextInt(range);
randomNumbers.add(e);
// Keep adding numbers until we reach 10
if (randomNumbers.size() <= 10)
{
if (randomNumbers.size() == 10)
g = 10;
g++;
randomNumbers.add(e);
}
}
// Return our random numbers as an ArrayList
ArrayList<Integer> al = new ArrayList<Integer>();
Iterator<Integer> iter = randomNumbers.iterator();
while(iter.hasNext())
{
al.add(iter.next());
}
return al;
}
I then throw these results at my pojo's so I can manage them easilly:
public void pojoOurQuestions()
{
// Copy our questions from ourQuestionsArray into our pojo's
// Loop for each JSONObject in ourQuestionsArray
for(int i = 0; i < ourQuestionsArray.size(); i++)
{
try
{
JSONObject jsonObject = ourQuestionsArray.get(i);
String s = jsonObject.getString("questionEntry");
// Need to put our question entries into our Pojo's
questionEntry = new ObjectMapper().readValue(s, QuestionEntry.class);
//System.out.println("Our questionEntry from pojo: " + questionEntry.toString());
} catch (JSONException e)
{
e.printStackTrace();
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I've not used JSON with Java before, the process of having to parse my results back and forth seems a untidy to me. Maybe I have got things wrong?