Finding min and max values with MongoDB Aggregation

Aggregation operations in MongoDB allow you to process documents to produce computed results. An example is to search for a min or max value. For documents that look like this:

{
  "_id" : ObjectId("5521ae8c0364d302910ec5eb"),
  "color" : "blue",
  "orderDate" : ISODate("2014-07-08T19:53:00Z")
  //other properties
}

You can find the min/earliest date in the collection for an document with matching color of blue with an aggregation query like this:

db.collectionName.aggregate(
[
{ "$match" : { "color":"blue" } },
{ "$group" : { "_id" : "$color",
first: { "$min" : "$orderDate"},
}
])

Implementing this with the Java Driver API looks like this:


DBObject match = new BasicDBObject("$match", new BasicDBObject("color", "blue"));

//$group
DBObject groupFields = new BasicDBObject( "_id", "$color");
groupFields.put("orderDate", new BasicDBObject( "$min", "$orderDate"));
DBObject group = new BasicDBObject("$group", groupFields);

List<DBObject> pipeline = Arrays.asList(match, group);

AggregationOutput output = col.aggregate(pipeline);
for (DBObject result : output.results()) {
//iterate results, only 1 for $min
}

Simplest AngularJS Service and a Jasmine unit test

The syntax for creating an AnguarJS service is rather alien to me as a Java developer, so I struggled to get this right, despite looking at and trying a number of different examples from different articles and howtos.

I think I’ve got this distilled to a simplest possible example now, so for future reference, this is a bare minimum service:

[code language=”javascript”]

angular.module(‘AppName.services’, [])
.factory(‘exampleService’, function () {

var serviceImpl = {};

//methods on service here

return serviceImpl;
});

[/code]

The syntax for implementing methods on the Service is like this (insert into where the comment is in the above example:

[code]

return {
exampleMethod: function (exampleParam1) {
var result;

//do something here

return result;
}
};

[/code]

A simple Jasmine test for a Service looks like this:

[code]

describe(‘Example service’, function () {
var exampleService;

it("Should be something here", function () {

var $injector = angular.injector([ ‘AppName.services’ ]);

exampleService = $injector.get( ‘exampleService’ );
var result = exampleService.exampleMethod(1);
expect(result).toBe(1);
});

});
[/code]

Using mocks with Jasmine tests for AngularJS

I’m not entirely sure I understand exactly what is going on here or how this is working, but posting to refer back to later.

I have a controller that’s using $interval. Rather than coding a delay into my test in order to let time pass in real time before I do my assertions, a better approach would be to mock out $interval so you can move elapsed time forward programmatically, which is a much better approach.

Luckily the ngMock package provides mocks for most things, including $interval. To move time, you call $interval.flush(millis);

[code language=”javascript”]

describe(‘Test variable date timer’, function () {

it(‘Runs for 1 iteration, 30min interval, adds 30 mins’, function () {
var $scope = {};
angular.mock.inject(function ($controller, _$interval_) {
$interval = _$interval_;
controller = $controller(‘VariableRateDateCtrl’, {$scope: $scope, $interval: $interval});

});

$scope.iterations = 1;
$scope.timeInterval = 30;
$scope.date = moment();
startDate = $scope.date.clone();

$scope.start();
$interval.flush(1000 * $scope.iterations);

endDate = $scope.date;
expectedEndDate = startDate.clone().add($scope.timeInterval, ‘minutes’);
expect(endDate.isAfter(startDate)).toEqual(true);
expect(endDate).toEqual(expectedEndDate);
});[/code]