Eliot,
Sorry about that... I wasn't sure if the code would be helpful in
this case. I experimented some more and something interesting came up.
First off, I'm using CFML (ColdFusion) which uses the java driver. In
CFML, adding the call to db.getLastError() added a few ms onto the
saves but didn't chop any time off the group(). However, when I
ported it all over to straight java, getLastError() added a lot of
time onto the saves but got the group() down to the same amount of
time as when I run it without the saves in front of it... basically,
confirming what you indicated earlier. In the straight java case, the
"total" time when doing save-then-group was about the same... it's
just that adding getLastError() moved the time up into the save block
and out of the group() block. So, no biggie.
At this point, I'd consider this just some weirdness with CF, and
nothing I'm concerned about. At least now I understand why the saves
appear to affect the subsequent group(), which is that the subsequent
group() needs to wait for those saves to complete, and in CF even with
getLastError it appears that they are complete but in fact they must
not be.
Here's the code, for posterity. Please note that this is just "toy"
code I'm using to teach myself how to use Mongo.
Thanks! As far as I'm concerned, case closed.
Best,
Marc
//Straight Java version:
//insert some new ratings
String vid = "4bf3ec44992a000000002e8a";
DB vicesDB = mongo.getDB("vices");
DBCollection ratingsColl = vicesDB.getCollection("ratings");
long thisRunKey = System.currentTimeMillis();
long startInserts = System.currentTimeMillis();
for(int i=1; i<=100;i++){
String thisRunUserName = "marc_" + thisRunKey + "_" +i;
BasicDBObject update = new
BasicDBObject("U",thisRunUserName).append("R", 4).append("VID", vid);
BasicDBObject criteria = new
BasicDBObject("U",thisRunUserName).append("VID", vid);
ratingsColl.update(criteria,update,true,false);
vicesDB.getLastError();
}
System.out.println("Total insert time: " +
(System.currentTimeMillis()-startInserts));
//perform the group()
String jsFunction = "function(obj,agg){ agg.COUNT++;
agg.RATINGTOTAL += obj.R; }";
BasicDBObject key = new BasicDBObject("VID",true);
BasicDBObject cond = new
BasicDBObject("VID","4bf3ec44992a000000002e8a");
BasicDBObject initial = new BasicDBObject("RATINGTOTAL",
0).append("COUNT", 0);
long start = System.currentTimeMillis();
DBObject groupResult = ratingsColl.group(key, cond, initial,
jsFunction);
long total = System.currentTimeMillis()-start;
System.out.println("total group execution: " + total);
System.out.println(groupResult);
//CFML:
//loop and save ratings
for(i=1; i <= 100; i++){
saveRating(vice,
{name="marc_stogie_#getTickCount()#_#i#",value=randRange(1,5)});
}
//update the average rating for all ratings in the collection
viceDAO.updateAverageViceRating(vice);
public Vice function saveRating(Vice vice, Struct rating){
var updateDBO =
newDBObjectFromStruct({U=
rating.name,R=javacast("double",rating.value),vid=vice.getViceID()});
var criteriaDBO =
newDBObjectFromStruct({U=
rating.name,vid=vice.getViceID()});
ratingsColl.update(criteriaDBO,updateDBO,true,false);
vicesDB.getLastError();
return vice;
}
public Vice function updateAverageViceRating(Vice vice){
var criteria = newDBObject("VID",vice.getViceID());
var keys = newDBObject("VID",true);
var dbl = javacast("double",0);
var initial = newDBObjectFromStruct({RATINGTOTAL=dbl,COUNT=dbl});
var jsFunction = "function(obj,agg){
agg.COUNT++;
agg.RATINGTOTAL += obj.R;
}";
var groups = ratingsColl.group(keys,criteria,initial,jsFunction);
vice.setAverageRating( groups[1]["RATINGTOTAL"] / groups[1]
["COUNT"] );
save(vice);
return vice;