Skip to content

Instantly share code, notes, and snippets.

@fmaylinch
Last active March 30, 2016 11:24
Show Gist options
  • Save fmaylinch/2099bb924f620547c763 to your computer and use it in GitHub Desktop.
Save fmaylinch/2099bb924f620547c763 to your computer and use it in GitHub Desktop.
import static com.mongodb.QueryOperators.*;
@Override
public List<Coupon> findBuyersByMktc(String mktc, Date start, Date end)
{
final DBCursor cursor = coupons.find(obj()
.append(FIELD_MKTC, mktc)
.append(FIELD_PURCHASED_ON, obj(GTE, start).append(LT, end)));
return MongoUtil.cursorToList(cursor, Coupon.mongo2Java);
}
class Coupon {
// ... fields and g/setters ...
public static final F<DBObject,Coupon> mongo2Java = new F<DBObject, Coupon>() {
@Override
public Coupon f(DBObject obj)
{
Coupon result = new Coupon();
result.setId((ObjectId) obj.get(FIELD_ID));
result.setUserId((ObjectId) obj.get(FIELD_USER_ID));
result.setUserEmail((String) obj.get(FIELD_USER_EMAIL));
result.setPrice((Double) obj.get(FIELD_PRICE));
result.setCouponState(CouponState.values()[((Integer) obj.get(FIELD_COUPON_STATE))]);
// ...
return result;
}
};
}
import com.mongodb.*;
import org.bson.types.ObjectId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;
public class MongoUtil
{
// Note you can take query operators from QueryOperators
public static final int ASC = 1;
public static final int DESC = -1;
public static final String MATCH = "$match";
public static final String PROJECT = "$project";
public static final String GROUP = "$group";
public static final String SORT = "$sort";
public static final String SKIP = "$skip";
public static final String LIMIT = "$limit";
/**
* Reads all the {@link DBCursor} and converts each {@link DBObject} found into
* an object of type {@link T}, using the given function.
*/
public static <T> List<T> cursorToList(Cursor cursor, F<DBObject,T> mongoToJava) {
try {
List<T> result = new ArrayList<T>();
while (cursor.hasNext()) {
result.add(mongoToJava.f(cursor.next()));
}
return result;
}
finally
{
cursor.close();
}
}
/**
* If the {@link DBCursor} has anything, converts the first {@link DBObject} found into
* an object of type {@link T}, using the given function. Otherwise returns null.
*/
public static <T> T getOne(Cursor cursor, F<DBObject,T> mongoToJava) {
try {
if (cursor.hasNext()) {
return mongoToJava.f(cursor.next());
} else {
return null;
}
}
finally
{
cursor.close();
}
}
/**
* Reads all the {@link DBCursor} and converts each {@link DBObject} found into
* an object of type {@link T}, using the given function, and passes those converted objects to the callback.
*/
public static <T> void processCursor(Cursor cursor, F<DBObject,T> mongoToJava, Callback<T> callback)
{
try {
while (cursor.hasNext()) {
callback.call(mongoToJava.f(cursor.next()));
}
}
finally
{
cursor.close();
}
}
/**
* Converts the source to an object of type {@link T} using the {@link Factory} and {@link Configurator}.
* The {@link Factory} creates an instance of type {@link T} and the {@link Configurator} configures
* that object using the source.
*/
public static <S,U,T extends U> T convert(S source, Factory<T> factory, Configurator<S,U> configurator) {
T target = null;
if (source != null) {
target = factory.f();
configurator.call(source, target);
}
return target;
}
/**
* This is like {@link #convert(Object, Factory, Configurator)} but the target is
* fixed to type {@link BasicDBObject}.
*/
public static <S> BasicDBObject convert2Mongo(S source, Configurator<S,BasicDBObject> configurator) {
return convert(source, dbObjectFactory, configurator);
}
private static Factory<BasicDBObject> dbObjectFactory = new Factory<BasicDBObject>() {
@Override
public BasicDBObject f() {
return new BasicDBObject();
}
};
/**
* Reads all the {@link DBCursor} and converts each {@link DBObject} found into
* an object of type {@link T}, using the given {@link Factory} and {@link Configurator}.
*/
public static <U,T extends U> List<T> cursorToList(DBCursor cursor, Factory<T> factory, Configurator<DBObject,U> configurator) {
try {
List<T> result = new ArrayList<T>();
while (cursor.hasNext()) {
result.add(convert(cursor.next(), factory, configurator));
}
return result;
}
finally
{
cursor.close();
}
}
/**
* Returns a list, converting each {@link DBObject} into an object of type {@link T} using the given function.
*/
public static <T> List<T> iterableToList(Iterable<DBObject> iterable, F<DBObject,T> mongoToJava) {
List<T> result = new ArrayList<T>();
for (DBObject obj : iterable) {
result.add(mongoToJava.f(obj));
}
return result;
}
/**
* Returns a list, converting each {@link DBObject} into an object of type {@link T} using the {@link Factory} and {@link Configurator}.
*/
public static <U,T extends U> List<T> iterableToList(Iterable<DBObject> iterable, Factory<T> factory, Configurator<DBObject,U> configurator) {
List<T> result = new ArrayList<T>();
for (DBObject obj : iterable) {
result.add(convert(obj, factory, configurator));
}
return result;
}
public static BasicDBObject obj(String key, Object value) {
return new BasicDBObject(key, value);
}
public static BasicDBObject obj() {
return new BasicDBObject();
}
public static BasicDBList list(Collection<?> elems) {
final BasicDBList result = new BasicDBList();
result.addAll(elems);
return result;
}
public static BasicDBList list(Object... elems) {
return list(Arrays.asList(elems));
}
public static ObjectId toId(String id) {
return new ObjectId(id);
}
public static List<ObjectId> toIds(List<String> ids)
{
final List<ObjectId> result = new ArrayList<ObjectId>();
for (String id : ids) result.add(toId(id));
return result;
}
/**
* This is equivalent to obj(field, obj("$in", values)) but using the "$or" operator.
* Useful when the "$in" operator is not available, like in the "$project" clause.
*/
public static BasicDBObject inUsingOr(String field, List<?> values)
{
return obj("$or", buildConditions(field, values));
}
private static List<DBObject> buildConditions(String field, List<?> values)
{
final List<DBObject> result = new ArrayList<DBObject>();
for (Object value : values) {
result.add(obj("$eq", Arrays.asList(field, value)));
}
return result;
}
/** Reference to a property name for clauses like project or group */
public static String ref(String propertyName) {
return "$" + propertyName;
}
}
// Put these clases in their files
public interface Factory<T> extends F0<T> { }
public interface Configurator<S,T> extends Callback2<S,T> { }
/** Represents a function that doesn't get any parameter and returns a {@link Result} */
public interface F0<Result> {
Result f();
}
/** Represents a function that takes one parameter {@link Param} and returns a {@link Result} */
public interface F0<Param,Result> {
Result f(Param p);
}
/** Callback that does something with its parameter {@link P} */
public interface Callback<P> {
void call(P p);
}
/** Callback that does something with its parameters {@link P1} and {@link P2} */
public interface Callback2<P1, P2> {
void call(P1 p1, P2 p2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment