Java tutorial
package org.basex.modules; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import org.basex.modules.errors.MongoDBErrors; import org.basex.query.QueryException; import org.basex.query.func.FuncOptions; import org.basex.query.value.Value; import org.basex.query.value.item.Bln; import org.basex.query.value.item.Int; import org.basex.query.value.item.Item; import org.basex.query.value.item.QNm; import org.basex.query.value.item.Str; import org.basex.query.value.map.Map; import org.basex.query.value.type.SeqType; import com.mongodb.AggregationOutput; import com.mongodb.BasicDBObject; import com.mongodb.CommandResult; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBEncoder; import com.mongodb.DBObject; import com.mongodb.MapReduceCommand; import com.mongodb.MapReduceCommand.OutputType; import com.mongodb.MapReduceOutput; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.MongoException; import com.mongodb.WriteResult; import com.mongodb.util.JSON; import com.mongodb.util.JSONParseException; /** * This is the primary class for MongoDb processing in Basex. * * @author BaseX Team 2005-14, BSD License * @author Prakash Thapa */ public class MongoDB extends Nosql { protected static final String LIMIT = "limit"; protected static final String SORT = "SORT"; protected static final String SKIP = "skip"; protected static final String COUNT = "count"; protected static final String EXPLAIN = "explain"; protected static final String MAP = "map"; protected static final String REDUCE = "reduce"; protected static final String QUERY = "query"; protected static final String FINALIZE = "finalalize"; /** URL of MongDB module. */ private static final String MONGO_URL = "http://basex.org/modules/mongodb"; /** QName of MongoDB options. */ private static final QNm Q_MONGODB = QNm.get("mongodb", "options", MONGO_URL); /** mongoclient instances. */ private HashMap<String, MongoClient> mongoClients = new HashMap<String, MongoClient>(); /** DB instances instances. */ private HashMap<String, DB> dbs = new HashMap<String, DB>(); /** Mongo Options instances. */ private HashMap<String, NosqlOptions> mongopts = new HashMap<String, NosqlOptions>(); public MongoDB() { super(Q_MONGODB); } /** * Connect MongoDB with it's url in the format of mongodb://root:root@localhost/test. * @param MongoDB URL for connection * @return Str Key of HashMap that contains all DB Object of Mongodb * connection instances. * @throws QueryException */ // public Str connection(final Str url) throws QueryException { // return connection(url, null); // } /** * Connect parameters in map like: {"host":"localhost","port":27017, * "database":"test", "username":"user", "password":"pass"}. * @param connectionMap * @return Str Key of HashMap that contains all DB Object of Mongodb * connection instances. * @throws QueryException */ public Str connection(final Map connectionMap) throws QueryException { final NosqlOptions opts = new NosqlOptions(); if (connectionMap != null) { new FuncOptions(Q_MONGODB, null).parse(connectionMap, opts); } if (opts.get(NosqlOptions.URL) != null) { return connection(Str.get(opts.get(NosqlOptions.URL)), connectionMap); } String handler = "Client" + mongoClients.size(); try { MongoClient mongoClient = new MongoClient((String) opts.get(NosqlOptions.HOST), (int) opts.get(NosqlOptions.PORT)); mongoClients.put(handler, mongoClient); char[] pass = (opts.get(NosqlOptions.PASSWORD) != null) ? opts.get(NosqlOptions.PASSWORD).toCharArray() : null; return mongoConnect(handler, opts.get(NosqlOptions.DATABASE), opts.get(NosqlOptions.USERNAME), pass, connectionMap); } catch (final MongoException ex) { throw MongoDBErrors.mongoExceptionError(ex); } catch (UnknownHostException ex) { throw MongoDBErrors.generalExceptionError(ex); } } /** * Mongodb connection with options. * @param url * @param options * @return * @throws QueryException */ public Str connection(final Str url, final Map options) throws QueryException { MongoClientURI uri = new MongoClientURI(url.toJava()); String handler = "mongoClient" + mongoClients.size(); try { MongoClient mongoClient = new MongoClient(uri); mongoClients.put(handler, mongoClient); return mongoConnect(handler, uri.getDatabase(), uri.getUsername(), uri.getPassword(), options); } catch (final MongoException ex) { throw MongoDBErrors.mongoExceptionError(ex); } catch (UnknownHostException ex) { throw MongoDBErrors.generalExceptionError(ex); } } /** * Mongodb connection with separate Hostname, port and database. * @param host hostname of server. * @param port Port Number * @param dbname Database name. * @return Str key of Hashmap that contains all DB Instances * @throws QueryException */ public Str connection(final Str host, final Int port, final Str database) throws QueryException { return connection(host, port, database, null, null, null); } /** * Mongodb connection with separate Hostname, port and database. * @param host hostname of server. * @param port Port Number * @param dbname Database name. * @param options * @return Str key of Hashmap that contains all DB Instances * @throws QueryException */ public Str connection(final Str host, final Int port, final Str database, final Map options) throws QueryException { return connection(host, port, database, options, null, null); } /** * Mongodb connection with separate Hostname, port and database. * @param host hostname of server. * @param port Port Number * @param dbname Database name. * @param options * @param username username of Mongodb * @param password password of Mongodb * @return Str key of Hashmap that contains all DB Instances * @throws QueryException */ public Str connection(final Str host, final Int port, final Str database, final Map options, final Str username, final Str password) throws QueryException { String handler = "Client" + mongoClients.size(); try { MongoClient mongoClient = new MongoClient((String) host.toJava(), (int) port.itr()); mongoClients.put(handler, mongoClient); char[] pass = (password != null) ? password.toJava().toCharArray() : null; String user = (String) ((username != null) ? username.toJava() : username); return mongoConnect(handler, database.toJava(), user, pass, options); } catch (final MongoException ex) { throw MongoDBErrors.mongoExceptionError(ex); } catch (UnknownHostException ex) { throw MongoDBErrors.generalExceptionError(ex); } } /** * This method take key of Hashmap, create DB object and store to another * Hashmap. * @param mongoClientHandler Key of Hashmap that contains all Mongoclient instances * @param database name of database to be connect * @param username user's name for mongodb Connect * @param password password of user to connect Mongodb * @param options Other nosql options like {"type":"json"} and so on * @return Str key of Hashmap that contains all DB Instances * @throws QueryException */ private Str mongoConnect(final String mongoClientHandler, final String database, final String username, final char[] password, final Map options) throws QueryException { final NosqlOptions opts = new NosqlOptions(); if (options != null) { new FuncOptions(Q_MONGODB, null).parse(options, opts); } MongoClient mongoClient = mongoClients.get(mongoClientHandler); final String dbh = "DB" + dbs.size(); try { DB db = mongoClient.getDB(database); if (username != null && password != null) { boolean auth = db.authenticate(username, password); if (!auth) { throw MongoDBErrors.unAuthorised(); } } dbs.put(dbh, db); if (options != null) { mongopts.put(dbh, opts); } return Str.get(dbh); } catch (final MongoException ex) { throw MongoDBErrors.mongoExceptionError(ex); } } /** * This Method take Map as parameters and create array of <code>DBObject</code> * of MongoDB in first level like {"a":{"b":"c"},"x":{"y":"z"}} here there * are two array with key "a" and "x" other will be be the key value parameter * inBasicDBObject. * * <blockquote><pre> * DBObject obj = new BasicDBObject(); * obj.put( "foo", "bar" ); * </pre></blockquote> * @param map Basex Map * @return array of DBObject * @throws QueryException */ private DBObject[] mapToDBObjectArray(final Map map) throws QueryException { if ((map != null) && (!map.isEmpty())) { try { final Value keys = map.keys(); DBObject[] dbObject = null; int length = (int) keys.size(); if (length > 0) { dbObject = new BasicDBObject[length]; int i = 0; for (Item key : keys) { final Value value = map.get(key, null); DBObject singleObject = new BasicDBObject(); if (value instanceof Map) { singleObject.put(((Str) key).toJava(), this.mapToDBObject((Map) value)); } else if (value.type().instanceOf(SeqType.ITR_OM)) { long l = ((Item) value).itr(null); singleObject.put(((Str) key).toJava(), l); } else { singleObject.put(((Str) key).toJava(), value.toJava()); } dbObject[i] = singleObject; i++; } } else { dbObject = null; } return dbObject; } catch (Exception e) { MongoDBErrors.generalExceptionError(e); } } return null; } /** * This Method convert Basex Map to MongoDB's DBObject. * {"foo":"bar"} * <blockquote><pre> * DBObject obj = new BasicDBObject(); * obj.put( "foo", "bar" ); * </pre></blockquote> * @param map Basex's Map * @return DBObject * @throws QueryException */ private DBObject mapToDBObject(final Map map) throws QueryException { if (map != null) { final DBObject dbObject = new BasicDBObject(); final Value keys = map.keys(); for (Item key : keys) { final Value value = map.get(key, null); if (value instanceof Map) { dbObject.put(((Str) key).toJava(), this.mapToDBObject((Map) value)); } else if (value.type().instanceOf(SeqType.ITR_OM)) { long l = ((Item) value).itr(null); dbObject.put(((Str) key).toJava(), l); } else { dbObject.put(((Str) key).toJava(), value.toJava()); } } return dbObject; } return null; } /** * This Method gives the DB Handler from Hashmap with given Key. * @param handler key for Hashmap that contains all DB objects * @return DB Object * @throws QueryException */ protected DB getDbHandler(final Str handler) throws QueryException { final DB db = dbs.get(handler.toJava()); if (db == null) throw MongoDBErrors.mongoDBError(handler.toJava()); return db; } /** * Get Mongodb Options for particular database handler. * @param handler Database handler * @return MongoOptions object */ private NosqlOptions getMongoOption(final Str handler) { NosqlOptions opt = mongopts.get(handler.toJava()); if (opt != null) return opt; else return null; } /** * All the result from Mongodb will come to this Method in the form of Json String. * First it checks the assigned NOSQL {@link NosqlOptions} options and then * return the final result {@link #finalResult(Str, Str)} process by parent * class[{@link Nosql}]. * @param handler Database handler * @param json Str object that contains Json string * @return Item * @throws Exception */ private Item returnResult(final Str handler, final Str json) throws Exception { NosqlOptions opt = getMongoOption(handler); if (json != null) { if (opt != null) { return finalResult(json, opt); } else { return finalResult(json, null); } } else { return null; } } /** * Convert collection result(DBCursor) into Item {@link Item} element. * @param result DBCursor * @return Item * @throws QueryException */ private Item cursorToItem(final Str handler, final DBCursor cursor) throws QueryException { if (cursor != null) { try { if (cursor.count() == 1) { Iterator<DBObject> row = cursor.iterator(); return objectToItem(handler, row.next()); } else { final Str json = Str.get(JSON.serialize(cursor)); return returnResult(handler, json); } } catch (final Exception ex) { throw MongoDBErrors.generalExceptionError(ex); } } else { return null; } } /** * Convert collection DBObject into Item {@link Item} element. * @param object DBObject (one row result) * @return Item * @throws QueryException */ private Item objectToItem(final Str handler, final DBObject object) throws QueryException { if (object != null) { try { final Str json = Str.get(JSON.serialize(object)); return returnResult(handler, json); } catch (final Exception ex) { throw MongoDBErrors.generalExceptionError(ex); } } else { return null; } } /** * Take string as Str and return DBObject of mongodb. * @param string * @return * @throws QueryException */ protected DBObject getDbObjectFromStr(final Item item) throws QueryException { try { if (item instanceof Map) { return mapToDBObject((Map) item); } else if (item instanceof Str) { final String string = itemToString(item); return (DBObject) JSON.parse(string); } else { throw MongoDBErrors.generalExceptionError("Number Expected for key '"); } } catch (JSONParseException e) { throw MongoDBErrors.jsonFormatError(item.toJava()); } } /** * Return all the collections in current database. * @param handler DB handler. * @return Item * @throws QueryException */ public Item collections(final Str handler) throws QueryException { final DB db = getDbHandler(handler); Set<String> col = db.getCollectionNames(); BasicDBObject collection = new BasicDBObject("collections", col); try { return objectToItem(handler, (DBObject) collection); } catch (JSONParseException e) { throw MongoDBErrors.jsonFormatError(col); } } /** * MongoDB find() without any parameters. eg. db.collections.find() * @param handler Database handler * @param col Collection name * @return result in xml element * @throws QueryException */ public Item find(final Str handler, final Item col) throws QueryException { return find(handler, col, null, null, null); } /** * MongoDB find() with query. eg. db.collections.find({'_id':2}) * @param handler Database handler * @param col collection * @param query conditions * @return Item * @throws QueryException */ public Item find(final Str handler, final Item col, final Item query) throws QueryException { return find(handler, col, query, null, null); } /** * MongoDB find() Query and Projection. * @param handler Database handler * @param col collection * @param query conditions * @param field projection on Mongodb * @return xml elements * @throws QueryException */ public Item find(final Str handler, final Str col, final Str query, final Item opt) throws QueryException { return find(handler, col, query, opt, null); } /** * MongoDB find with all parameters. * @param handler Database handler * @param col collection * @param query Query parameters * @param opt options in Map like: {"limit":2} * @param field Projection * @return Item * @throws QueryException */ public Item find(final Str handler, final Item col, final Item query, final Item opt, final Item projection) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { DBObject p = null; if (opt != null && opt instanceof Str) { p = getDbObjectFromStr(opt); } else if (projection != null && projection instanceof Str) { p = getDbObjectFromStr(projection); } final DBObject q = query != null ? getDbObjectFromStr(query) : null; final DBCollection coll = db.getCollection(itemToString(col)); final DBCursor cursor = coll.find(q, p); Map options = null; options = (opt != null && opt instanceof Map) ? (Map) opt : (projection != null && projection instanceof Map) ? (Map) projection : null; if (options != null) { Value keys = options.keys(); for (final Item key : keys) { if (!(key instanceof Str)) throw MongoDBErrors.generalExceptionError("String expected " + key.toJava()); final String k = ((Str) key).toJava(); final Value v = options.get(key, null); if (v instanceof Str || v.type().instanceOf(SeqType.ITR)) { if (k.equals(LIMIT)) { if (v.type().instanceOf(SeqType.ITR_OM)) { long l = ((Item) v).itr(null); cursor.limit((int) l); } else { throw MongoDBErrors .generalExceptionError("Number Expected for key '" + key.toJava() + "'"); } } else if (k.equals(SKIP)) { //cursor.skip(Token.toInt(v)); } else if (k.equals(SORT)) { BasicDBObject sort = new BasicDBObject(k, v); sort.append("name", "-1"); cursor.sort((DBObject) sort); } else if (k.equals(COUNT)) { int count = cursor.count(); BasicDBObject res = new BasicDBObject(); res.append("count", count); return objectToItem(handler, res); } else if (k.equals(EXPLAIN)) { DBObject result = cursor.explain(); return objectToItem(handler, result); } } else if (v instanceof Map) { } else { throw MongoDBErrors.generalExceptionError("Invalid value 2..."); } } } return cursorToItem(handler, cursor); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e.getMessage()); } finally { db.requestDone(); } } /** * Mongodb's findOne() function. * @param handler * @param col * @return Item * @throws QueryException */ public Item findOne(final Str handler, final Item col) throws QueryException { return findOne(handler, col, null, null); } /** * Mongodb's findOne({'_id':2}) function with query. * @param handler * @param col * @param query * @return Item * @throws QueryException */ public Item findOne(final Str handler, final Item col, final Item query) throws QueryException { return findOne(handler, col, query, null); } /** * findOne with query and projection projection. * @param handler * @param col * @param query * @param field * @return Item * @throws QueryException */ public Item findOne(final Str handler, final Item col, final Item query, final Item projection) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { final DBObject p = projection != null ? getDbObjectFromStr(projection) : null; final DBObject q = query != null ? getDbObjectFromStr(query) : null; final DBCollection coll = db.getCollection(itemToString(col)); final DBObject cursor = coll.findOne(q, p); return objectToItem(handler, cursor); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e.getMessage()); } finally { db.requestDone(); } } /** * Insert data in MongoDB. * @param handler DB Handler * @param col Collection name * @param insertString string to insert in json formart or in Basex's Map * @return Item result from Mongodb. * @throws Exception */ public Item insert(final Str handler, final Str col, final Str insertString) throws Exception { final DB db = getDbHandler(handler); db.requestStart(); try { DBObject obj = getDbObjectFromStr(insertString); WriteResult wr = db.getCollection(col.toJava()).insert(obj); return returnResult(handler, Str.get(wr.toString())); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(db.getLastError().getString("err")); } finally { db.requestDone(); } } /** * Mongodb update with two parameters like update({},{}). * @param handler * @param col collection's name * @param insertString Json Str or Basex's Map * @return Item * @throws Exception */ public Item update(final Str handler, final Item col, final Item query, final Str updatestring) throws Exception { return update(handler, col, query, updatestring, null, null); } /** * Mongodb update with 4 parameters like update({},{}, upsert, multi). * @param handler Db Handler string * @param col Collection name * @param updatestring String to be updated * @param upsert true/false for mongodb upsert(Json Str or Map) * @param multi true/false for mongodb multi * @return Item * @throws Exception */ public Item update(final Str handler, final Item col, final Item query, final Str updatestring, final Bln upsert, final Bln multi) throws Exception { final DB db = getDbHandler(handler); db.requestStart(); try { DBObject q = getDbObjectFromStr(query); DBObject updateValue = getDbObjectFromStr(updatestring); WriteResult wr; if (upsert != null && multi != null) { wr = db.getCollection(itemToString(col)).update(q, updateValue, upsert.toJava(), multi.toJava()); } else { wr = db.getCollection(itemToString(col)).update(q, updateValue); } return returnResult(handler, Str.get(wr.toString())); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(db.getLastError().getString("err")); } finally { db.requestDone(); } } /** * Mongodb Save function. * @param handler DB handler * @param col collection name * @param saveStr string to save(Map or Josn) * @return Item * @throws Exception */ public Item save(final Str handler, final Str col, final Item saveStr) throws Exception { final DB db = getDbHandler(handler); db.requestStart(); try { WriteResult wr = db.getCollection(col.toJava()).save(getDbObjectFromStr(saveStr)); return returnResult(handler, Str.get(wr.toString())); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(db.getLastError().getString("err")); } finally { db.requestDone(); } } /** * Mongodb remove(). This will delete the document with specified query. * @param handler * @param col Collection name; * @param query Query to select document.(Map or Json Str) * @throws QueryException */ public void remove(final Str handler, final Item col, final Item query) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { db.getCollection(itemToString(col)).remove(getDbObjectFromStr(query)); DBObject err = db.getLastError(); if (err != null) { throw MongoDBErrors.generalExceptionError(err.get("err").toString()); } } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * Mongodb Aggregate function with single aggregation parameter. * @param handler database handler * @param col collection name * @param first Only one parameter of Aggregate function. * @return Item * @throws Exception */ public Item aggregate(final Str handler, final Item col, final Item first) throws Exception { return aggregate(handler, col, first, null); } /** * This method is for aggregating with all pipeline options. All the options * should be given in sequence like: ('$group:{..}',...). * @param handler database handler * @param col collection name * @param first aggregation compulsary * @param additionalOps other pipeline options in sequence. * @return Item * @throws QueryException */ public Item aggregate(final Str handler, final Item col, final Item first, final Value additionalOps) throws Exception { final DB db = getDbHandler(handler); AggregationOutput agg; DBObject[] pipeline = null; if (additionalOps != null && (!additionalOps.isEmpty())) { if (additionalOps instanceof Map) { pipeline = mapToDBObjectArray((Map) additionalOps); } else { int length = (int) additionalOps.size(); if (length > 0) { pipeline = new BasicDBObject[length]; int i = 0; for (Item x : additionalOps) { pipeline[i++] = getDbObjectFromStr(x); } } else { pipeline = null; } } } db.requestStart(); try { if (additionalOps != null && (!additionalOps.isEmpty())) { agg = db.getCollection(itemToString(col)).aggregate(getDbObjectFromStr(first), pipeline); } else { agg = db.getCollection(itemToString(col)).aggregate(getDbObjectFromStr(first)); } final Iterable<DBObject> d = agg.results(); return returnResult(handler, Str.get(JSON.serialize(d))); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e.getMessage()); } finally { db.requestDone(); } } /** * count numbers of documents in a collection. * @param handler * @param col * @return number * @throws QueryException */ public long count(final Str handler, final Item col) throws QueryException { final DB db = getDbHandler(handler); long count = db.getCollection(itemToString(col)).count(); return count; } /** * Copy data from One collection to another collection within same Database. * @param handler * @param source Source collection name * @param dest Destination Collection name. * @throws QueryException */ public void copy(final Str handler, final Item source, final Item dest) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { List<DBObject> cursor = db.getCollection(itemToString(source)).find().toArray(); db.getCollection(itemToString(dest)).insert(cursor); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * Copy collection from one Database insert to another database. * @param handler Mongodb Connection for source database * @param source source collection * @param handlerDest Mongodb Connection for Destination database * @param dest Destination Collection * @throws QueryException */ public void copy(final Str handler, final Item source, final Str handlerDest, final Item dest) throws QueryException { final DB db = getDbHandler(handler); final DB dbDestionation = getDbHandler(handlerDest); db.requestStart(); try { List<DBObject> cursor = db.getCollection(itemToString(source)).find().toArray(); dbDestionation.getCollection(itemToString(dest)).drop(); dbDestionation.getCollection(itemToString(dest)).insert(cursor); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * Drop collection from a database. * @param handler * @param col collection name * @throws QueryException */ public void drop(final Str handler, final Item col) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { db.getCollection(itemToString(col)).drop(); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * MongoDB runCommand() function. * @param handler * @param command Command to Execute * @throws Exception */ public Item runCommand(final Str handler, final Item command) throws Exception { return runCommand(handler, command, null); } /** * MongoDB runCommand() function with integer as parameter. * @param handler * @param command command to execute in Map or JSON or simply String * @param options integer options. * @return Item * @throws Exception */ public Item runCommand(final Str handler, final Item command, final Int options) throws Exception { final DB db = getDbHandler(handler); db.requestStart(); try { CommandResult result = null; if (command instanceof Map) { DBObject cmd = mapToDBObject((Map) command); if (options != null) { result = db.command(cmd, (DBEncoder) options.toJava()); } else { result = db.command(cmd); } } else { result = db.command(((Str) command).toJava()); } return returnResult(handler, Str.get(result.toString())); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * Create Index in specified field. * @param handler * @param col name of collection * @param indexStr string to create index json or Map * @throws Exception */ public void ensureIndex(final Str handler, final Str col, final Item indexStr) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { db.getCollection(itemToString(col)).ensureIndex(getDbObjectFromStr(indexStr)); //return returnResult(handler, Str.get(result.toString())); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * drop Index in specified field. * @param handler * @param col name of collection * @param indexStr string to create index Json or Map * @throws Exception */ public void dropIndex(final Str handler, final Str col, final Item indexStr) throws QueryException { final DB db = getDbHandler(handler); db.requestStart(); try { db.getCollection(itemToString(col)).createIndex(getDbObjectFromStr(indexStr)); //return returnResult(handler, Str.get(result.toString())); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * take DB handler as parameter and get MongoClient and then close it. * @param handler DB handler * @throws QueryException */ public void close(final Str handler) throws QueryException { String ch = handler.toJava(); try { final MongoClient client = (MongoClient) getDbHandler(handler).getMongo(); if (client == null) throw MongoDBErrors.mongoDBError(ch); client.close(); } catch (MongoException e) { throw MongoDBErrors.mongoDBError(e); } } /** * This method is implemented for MongoDB Mapreduce. * @param handler Database Handler. * @param col Collection name * @param map Map method * @param reduce Reduce Method * @return Item * @throws Exception */ public Item mapreduce(final Str handler, final Str col, final Str map, final Str reduce) throws Exception { return mapreduce(handler, col, map, reduce, null, null, null); } /** * Mongodb Mapreduce function with 2 parameters. * @param handler Database Handler. * @param col Collection name * @param map Map method * @param reduce Reduce Method * @return Items * @throws Exception */ public Item mapreduce(final Str handler, final Str col, final Str map, final Str reduce, final Item finalalize) throws Exception { return mapreduce(handler, col, map, reduce, finalalize, null, null); } /** * Mongodb Mapreduce function with 2 parameters. * @param handler Database Handler. * @param col Collection name * @param map Map method * @param reduce Reduce Method * @return Items * @throws Exception */ public Item mapreduce(final Str handler, final Str col, final Str map, final Str reduce, final Item finalalize, final Item query) throws Exception { return mapreduce(handler, col, map, reduce, finalalize, query, null); } /** * Mongodb Mapreduce function with 3 parameters, Map, reduce and query Option. * @param handler Database Handler. * @param col Collection name * @param map Map method * @param reduce Reduce Method * @param query Selection options. * @return Items. * @throws Exception */ public Item mapreduce(final Str handler, final Str col, final Str map, final Str reduce, final Item finalalize, final Item query, final Map options) throws Exception { final DB db = getDbHandler(handler); if (map == null) { throw MongoDBErrors.generalExceptionError("Map function cannot be empty in Mapreduce"); } final DBObject q = query != null ? getDbObjectFromStr(query) : null; final DBCollection collection = db.getCollection(itemToString(col)); String out = null; String outType = null; OutputType op = MapReduceCommand.OutputType.INLINE; if (options != null) { for (Item k : options.keys()) { String key = (String) k.toJava(); if (key.equals("outputs")) { out = (String) options.get(k, null).toJava(); } if (key.equals("outputype")) { outType = (String) options.get(k, null).toJava(); } } if (out != null) { if (outType.toUpperCase().equals("REPLACE")) { op = MapReduceCommand.OutputType.REPLACE; } else if (outType.toUpperCase().equals("MERGE")) { op = MapReduceCommand.OutputType.MERGE; } else if (outType.toUpperCase().equals("REDUCE")) { op = MapReduceCommand.OutputType.REDUCE; } } } db.requestStart(); try { MapReduceCommand cmd = new MapReduceCommand(collection, map.toJava(), reduce.toJava(), out, op, q); if (finalalize != null) { cmd.setFinalize((String) finalalize.toJava()); } final MapReduceOutput outcmd = collection.mapReduce(cmd); return returnResult(handler, Str.get(JSON.serialize(outcmd.results()))); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } /** * Mapreduce all functions in xquery's Map like :{"map":"function(){..}" * , "reduce":"function(){}"}. * @param handler * @param col collection name * @param options all options of Mapreduce including "map" in key. * @return * @throws Exception */ public Item mapreduce(final Str handler, final Str col, final Map options) throws Exception { if (options == null) { throw MongoDBErrors.generalExceptionError("Map optoins are empty"); } final DB db = getDbHandler(handler); final DBCollection collection = db.getCollection(itemToString(col)); String out = null; String outType = null; String map = null; String reduce = null; DBObject query = null; DBObject sort = null; int limit = 0; String finalalize = null; OutputType op = MapReduceCommand.OutputType.INLINE; for (Item k : options.keys()) { String key = (String) k.toJava(); Value val = options.get(k, null); String value = (String) val.toJava(); if (key.toLowerCase().equals("map")) { map = (String) value; } else if (key.toLowerCase().equals("reduce")) { reduce = value; } else if (key.toLowerCase().equals("outputs")) { out = value; } else if (key.toLowerCase().equals("outputype")) { outType = value; } else if (key.toLowerCase().equals("limit")) { if (val.type().instanceOf(SeqType.ITR_OM)) { long l = ((Item) val).itr(null); limit = (int) l; } else { throw MongoDBErrors.generalExceptionError(" Expected integer Value"); } } else if (key.toLowerCase().equals(SORT)) { sort = getDbObjectFromStr(Str.get(value)); } else if (key.toLowerCase().equals(QUERY)) { query = getDbObjectFromStr(Str.get(value)); } else if (key.toLowerCase().equals(FINALIZE)) { finalalize = value; } } if (out != null && outType != null) { if (outType.toUpperCase().equals("REPLACE")) { op = MapReduceCommand.OutputType.REPLACE; } else if (outType.toUpperCase().equals("MERGE")) { op = MapReduceCommand.OutputType.MERGE; } else if (outType.toUpperCase().equals("REDUCE")) { op = MapReduceCommand.OutputType.REDUCE; } } else if (out != null) { op = MapReduceCommand.OutputType.REPLACE; } if (map == null) { throw MongoDBErrors.generalExceptionError("Map function cannot be empty"); } db.requestStart(); try { MapReduceCommand cmd = new MapReduceCommand(collection, map, reduce, out, op, query); if (finalalize != null) { cmd.setFinalize(finalalize); } if (limit != 0) { cmd.setLimit(limit); } if (sort != null) { cmd.setSort(sort); } final MapReduceOutput outcmd = collection.mapReduce(cmd); return returnResult(handler, Str.get(JSON.serialize(outcmd.results()))); } catch (MongoException e) { throw MongoDBErrors.generalExceptionError(e); } finally { db.requestDone(); } } }