All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.taimos.dvalin.mongo.MongoDBDataAccess Maven / Gradle / Ivy

There is a newer version: 1.35
Show newest version
package de.taimos.dvalin.mongo;

import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceOutput;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import de.taimos.dvalin.daemon.spring.InjectionUtils;
import org.bson.types.ObjectId;
import org.jongo.Find;
import org.jongo.Jongo;
import org.jongo.MongoCollection;
import org.jongo.ResultHandler;
import org.jongo.Update;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Repository
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MongoDBDataAccess {

    private final MongoDatabase db;
    private final Class entityClass;
    private final MongoCollection collection;

    @Autowired
    public MongoDBDataAccess(Jongo jongo, MongoDatabase db, InjectionPoint ip) {
        this.db = db;
        this.entityClass = (Class) InjectionUtils.getGenericType(ip);
        this.collection = jongo.getCollection(this.getCollectionName());
    }

    public String getCollectionName() {
        return this.entityClass.getSimpleName();
    }

    public Class getEntityClass() {
        return this.entityClass;
    }

    /**
     * runs a map-reduce-job on the collection. same as {@link #mapReduce(String, DBObject, DBObject, Map, MapReduceResultHandler)
     * mapReduce(name, null, null, null, conv)}
     *
     * @param   the type of the result class
     * @param name the name of the map-reduce functions
     * @param conv the converter to convert the result
     * @return an {@link Iterable} with the result entries
     */
    public final  Iterable mapReduce(String name, final MapReduceResultHandler conv) {
        return this.mapReduce(name, null, null, null, conv);
    }

    /**
     * runs a map-reduce-job on the collection. The functions are read from the classpath in the folder mongodb. The systems reads them from
     * files called <name>.map.js, <name>.reduce.js and optionally <name>.finalize.js. After this the result is converted
     * using the given {@link MapReduceResultHandler}
     *
     * @param    the type of the result class
     * @param name  the name of the map-reduce functions
     * @param query the query to filter the elements used for the map-reduce
     * @param sort  sort query to sort elements before running map-reduce
     * @param scope the global scope for the JavaScript run
     * @param conv  the converter to convert the result
     * @return an {@link Iterable} with the result entries
     * @throws RuntimeException if resources cannot be read
     */
    public final  Iterable mapReduce(String name, DBObject query, DBObject sort, Map scope, final MapReduceResultHandler conv) {
        String map = this.getMRFunction(name, "map");
        String reduce = this.getMRFunction(name, "reduce");

        MapReduceCommand mrc = new MapReduceCommand(this.collection.getDBCollection(), map, reduce, null, MapReduceCommand.OutputType.INLINE, query);
        String finalizeFunction = this.getMRFunction(name, "finalize");
        if(finalizeFunction != null) {
            mrc.setFinalize(finalizeFunction);
        }
        if(sort != null) {
            mrc.setSort(sort);
        }
        if(scope != null) {
            mrc.setScope(scope);
        }
        MapReduceOutput mr = this.collection.getDBCollection().mapReduce(mrc);
        return new ConverterIterable(mr.results().iterator(), conv);
    }

    private String getMRFunction(String name, String type) {
        try {
            InputStream stream = this.getClass().getResourceAsStream("/mongodb/" + name + "." + type + ".js");
            if(stream != null) {
                return StreamUtils.copyToString(stream, Charset.defaultCharset());
            }
            return null;
        } catch(IOException e) {
            throw new RuntimeException("Failed to read resource", e);
        }
    }

    public final List findList() {
        Iterable as = this.collection.find().sort("{_id:1}").as(this.entityClass);
        return this.convertIterable(as);
    }

    public List findList(String sortProp, Integer sortDirection, Integer limit, Integer skip) {
        return this.findSortedByQuery("{}", "{" + sortProp + ":" + sortDirection + "}", skip, limit);
    }

    /**
     * converts the given {@link Iterable} to a {@link List}
     *
     * @param 

the element type * @param as the {@link Iterable} * @return the converted {@link List} */ public final

List

convertIterable(Iterable

as) { List

objects = new ArrayList<>(); for(P mp : as) { objects.add(mp); } return objects; } /** * finds all elements matching the given query * * @param query the query to search for * @param params the parameters to replace # symbols * @return the list of elements found */ public final List findByQuery(String query, Object... params) { return this.findSortedByQuery(query, null, params); } /** * finds all elements matching the given query and sorts them accordingly * * @param query the query to search for * @param sort the sort query to apply * @param params the parameters to replace # symbols * @return the list of elements found */ public final List findSortedByQuery(String query, String sort, Object... params) { return this.findSortedByQuery(query, sort, (Integer) null, (Integer) null, params); } /** * finds all elements matching the given query and sorts them accordingly. With this method it is possible to specify a projection to * rename or filter fields in the result elements. Instead of returning objects it returns objects of type * as * * @param query the query to search for * @param sort the sort query to apply * @param projection the projection of fields to use * @param as the target to convert result elements to * @param params the parameters to replace # symbols * @param

the element type * @return the list of elements found */ public final

List

findSortedByQuery(String query, String sort, String projection, Class

as, Object... params) { return this.findSortedByQuery(query, sort, null, null, projection, as, params); } /** * finds all elements matching the given query and sorts them accordingly. With this method it is possible to specify a projection to * rename or filter fields in the result elements. Instead of returning objects it returns objects converted * by the given {@link ResultHandler} * * @param query the query to search for * @param sort the sort query to apply * @param projection the projection of fields to use * @param handler the handler to convert result elements with * @param params the parameters to replace # symbols * @param

the element type * @return the list of elements found */ protected final

List

findSortedByQuery(String query, String sort, String projection, ResultHandler

handler, Object... params) { return this.findSortedByQuery(query, sort, null, null, projection, handler, params); } /** * finds all elements matching the given query and sorts them accordingly * * @param query the query to search for * @param sort the sort query to apply * @param skip the number of elements to skip * @param limit the number of elements to fetch * @param params the parameters to replace # symbols * @return the list of elements found */ public final List findSortedByQuery(String query, String sort, Integer skip, Integer limit, Object... params) { return this.findSortedByQuery(query, sort, skip, limit, null, this.entityClass, params); } /** * finds all elements matching the given query and sorts them accordingly. With this method it is possible to specify a projection to * rename or filter fields in the result elements. Instead of returning objects it returns objects of type * as * * @param query the query to search for * @param sort the sort query to apply * @param skip the number of elements to skip * @param limit the number of elements to fetch * @param projection the projection of fields to use * @param as the target to convert result elements to * @param params the parameters to replace # symbols * @param

the element type * @return the list of elements found */ public final

List

findSortedByQuery(String query, String sort, Integer skip, Integer limit, String projection, Class

as, Object... params) { Find find = this.createFind(query, sort, skip, limit, projection, params); return this.convertIterable(find.as(as)); } /** * finds all elements matching the given query and sorts them accordingly. With this method it is possible to specify a projection to * rename or filter fields in the result elements. Instead of returning objects it returns objects converted * by the given {@link ResultHandler} * * @param query the query to search for * @param sort the sort query to apply * @param skip the number of elements to skip * @param limit the number of elements to fetch * @param projection the projection of fields to use * @param handler the handler to convert result elements with * @param params the parameters to replace # symbols * @param

the element type * @return the list of elements found */ public final

List

findSortedByQuery(String query, String sort, Integer skip, Integer limit, String projection, ResultHandler

handler, Object... params) { Find find = this.createFind(query, sort, skip, limit, projection, params); return this.convertIterable(find.map(handler)); } private Find createFind(String query, String sort, Integer skip, Integer limit, String projection, Object... params) { Find find = this.collection.find(query, params); if((sort != null) && !sort.isEmpty()) { find.sort(sort); } if((projection != null) && !projection.isEmpty()) { find.projection(projection); } if(skip != null) { find.skip(skip); } if(limit != null) { find.limit(limit); } return find; } /** * queries with the given string, sorts the result and returns the first element. null is returned if no element is found. * * @param query the query string * @param sort the sort string * @param params the parameters to replace # symbols * @return the first element found or null if none is found */ public final Optional findFirstByQuery(String query, String sort, Object... params) { Find find = this.collection.find(query, params); if((sort != null) && !sort.isEmpty()) { find.sort(sort); } Iterable as = find.limit(1).as(this.entityClass); Iterator iterator = as.iterator(); if(iterator.hasNext()) { return Optional.of(iterator.next()); } return Optional.empty(); } public final Optional findByObjectId(String id) { return Optional.ofNullable(this.collection.findOne(new ObjectId(id)).as(this.entityClass)); } public final Optional findByStringId(String id) { return Optional.ofNullable(this.collection.findOne("{\"_id\":#}", id).as(this.entityClass)); } /** * @param query the query string * @param parameter the parameters to replace # symbols * @return the number of elements matching the query */ public final long count(String query, Object... parameter) { return this.collection.count(query, parameter); } public final T save(T object) { this.collection.save(object); return object; } public final void deleteByObjectId(String id) { this.collection.remove(new ObjectId(id)); } public final void deleteByStringId(String id) { this.collection.remove("{\"_id\":#}", id); } public final void delete(String query, Object... parameter) { this.collection.remove(query, parameter); } public final Update update(ObjectId id) { return this.collection.update(id); } public final Update update(String query) { return this.collection.update(query); } public final Update update(String query, Object... parameter) { return this.collection.update(query, parameter); } @Deprecated public MongoCollection getCollection() { return this.collection; } public GridFSBucket getGridFSBucket(String bucket) { if(bucket == null || bucket.isEmpty()) { throw new IllegalArgumentException(); } return GridFSBuckets.create(this.db, bucket); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy