Java tutorial
/* * Copyright 2011 VZ Netzwerke Ltd * Copyright 2014 devbliss GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mongojack; import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.mongodb.client.model.ReplaceOptions; import org.bson.BsonObjectId; import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; import org.mongojack.internal.MongoJackModule; import org.mongojack.internal.object.document.DocumentObjectGenerator; import org.mongojack.internal.object.document.DocumentObjectTraversingParser; import org.mongojack.internal.query.QueryCondition; import org.mongojack.internal.util.DocumentSerializationUtils; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.mongodb.MongoBulkWriteException; import com.mongodb.MongoException; import com.mongodb.MongoWriteConcernException; import com.mongodb.MongoWriteException; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; import com.mongodb.annotations.Beta; import com.mongodb.client.AggregateIterable; import com.mongodb.client.FindIterable; import com.mongodb.client.MapReduceIterable; import com.mongodb.client.model.FindOneAndUpdateOptions; import com.mongodb.client.model.IndexOptions; import com.mongodb.client.model.ReturnDocument; import com.mongodb.client.model.UpdateOptions; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; /** * A DBCollection that marshals/demarshals objects to/from Jackson annotated * classes. It provides a very thin wrapper over an existing MongoCollection. * * A JacksonMongoCollection is threadsafe, with a few caveats: * * If you pass your own ObjectMapper to it, it is not thread safe to reconfigure * that ObjectMapper at all after creating it. The setWritePreference and a few * other methods on JacksonMongoCollection should not be called from multiple * threads * * @author James Roper * @since 1.0 */ @Beta public class JacksonMongoCollection<T> { private static final ObjectMapper DEFAULT_OBJECT_MAPPER = MongoJackModule.configure(new ObjectMapper()); private com.mongodb.client.MongoCollection<T> mongoCollection; private final ObjectMapper objectMapper; private final Class<?> view; private final Class<T> valueClass; private final JavaType type; private JacksonMongoCollection(com.mongodb.client.MongoCollection<?> mongoCollection, ObjectMapper objectMapper, Class<T> valueClass, Class<?> view) { this.objectMapper = objectMapper == null ? DEFAULT_OBJECT_MAPPER : objectMapper; this.view = view; JacksonCodecRegistry jacksonCodecRegistry = new JacksonCodecRegistry(this.objectMapper, this.view); jacksonCodecRegistry.addCodecForClass(valueClass); this.mongoCollection = mongoCollection.withDocumentClass(valueClass) .withCodecRegistry(jacksonCodecRegistry); ; this.valueClass = valueClass; this.type = this.objectMapper.constructType(valueClass); } /** * Get the underlying mongo collection * * @return The underlying mongo collection */ public com.mongodb.client.MongoCollection<?> getMongoCollection() { return mongoCollection; } /** * Inserts an object into the database. If the objects _id is null, the driver will generate one * * @param object * The object to insert * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoWriteException * If the write failed due some other failure specific to the insert command * @throws MongoException * If an error occurred */ public void insert(T object) throws MongoException, MongoWriteException, MongoWriteConcernException { mongoCollection.insertOne(object); } /** * Inserts an object into the database. If the objects _id is null, the driver will generate one * * @param object * The object to insert * @param concern * the write concern * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoWriteException * If the write failed due some other failure specific to the insert command * @throws MongoException * If an error occurred */ public void insert(T object, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { mongoCollection.withWriteConcern(concern).insertOne(object); } /** * Inserts objects into the database. if the objects' _id are null, they will be generated. * * @param objects * The objects to insert * @throws MongoBulkWriteException * If there's an exception in the bulk write operation * @throws MongoException * If an error occurred * */ public void insert(@SuppressWarnings("unchecked") T... objects) throws MongoException, MongoBulkWriteException { ArrayList<T> objectList = new ArrayList<>(objects.length); for (T object : objects) { objectList.add(object); } mongoCollection.insertMany(objectList); } /** * Inserts objects into the database. if the objects' _id are null, they will be generated. * * @param objects * The objects to insert * @param concern * the write concern * @throws MongoBulkWriteException * If there's an exception in the bulk write operation * @throws MongoException * If an error occurred */ public void insert(WriteConcern concern, @SuppressWarnings("unchecked") T... objects) throws MongoException, MongoBulkWriteException { ArrayList<T> objectList = new ArrayList<>(objects.length); for (T object : objects) { objectList.add(object); } mongoCollection.withWriteConcern(concern).insertMany(objectList); } /** * Inserts objects into the database. if the objects' _id are null, they will be generated. * * @param list * The objects to insert * @throws MongoBulkWriteException * If there's an exception in the bulk write operation * @throws MongoException * If an error occurred */ public void insert(List<T> list) throws MongoException, MongoBulkWriteException { mongoCollection.insertMany(list); } /** * Inserts objects into the database. if the objects' _id are null, they will be generated. * * @param list * The objects to insert * @param concern * the write concern * @throws MongoBulkWriteException * If there's an exception in the bulk write operation * @throws MongoException * If an error occurred */ public void insert(List<T> list, WriteConcern concern) throws MongoException { mongoCollection.withWriteConcern(concern).insertMany(list); } /** * Performs an update operation. * * @param query * search query for old object to update * @param document * a document describing the update, which may not be null. The update to apply must include only update operators. * @param upsert * if the database should create the element if it does not exist * @param concern * the write concern * @return The write result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateOne(Document query, Document document, boolean upsert, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { query = serializeFields(query); if (concern != null) { return mongoCollection.withWriteConcern(concern).updateOne(serializeFields(query), serializeFields(document), new UpdateOptions().upsert(upsert)); } else { return mongoCollection.updateOne(serializeFields(query), serializeFields(document), new UpdateOptions().upsert(upsert)); } } /** * Performs an update operation. * * @param query * search query for old object to update * @param document * a document describing the update, which may not be null. The update to apply must include only update operators. * @param upsert * if the database should create the element if it does not exist * @param concern * the write concern * @return The UpdateResult * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateMany(Document query, Document document, boolean upsert, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { query = serializeFields(query); if (concern != null) { return mongoCollection.withWriteConcern(concern).updateMany(serializeFields(query), serializeFields(document), new UpdateOptions().upsert(upsert)); } else { return mongoCollection.updateMany(serializeFields(query), serializeFields(document), new UpdateOptions().upsert(upsert)); } } /** * Performs an update operation. * * @param query * search query for old object to update * @param update * update with which to update <tt>query</tt> * @param upsert * if the database should create the element if it does not exist * @param concern * the write concern * @return The UpdateResult * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateOne(DBQuery.Query query, DBUpdate.Builder update, boolean upsert, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { if (concern != null) { return mongoCollection.withWriteConcern(concern).updateOne(serializeQuery(query), update.serializeAndGetAsDocument(objectMapper, type), new UpdateOptions().upsert(upsert)); } else { return mongoCollection.updateOne(serializeQuery(query), update.serializeAndGetAsDocument(objectMapper, type), new UpdateOptions().upsert(upsert)); } } /** * Performs an update operation. * * @param query * search query for old object to update * @param update * update with which to update <tt>query</tt> * @param upsert * if the database should create the element if it does not exist * @param concern * the write concern * @return The UpdateResult * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateMany(DBQuery.Query query, DBUpdate.Builder update, boolean upsert, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { if (concern != null) { return mongoCollection.withWriteConcern(concern).updateMany(serializeQuery(query), update.serializeAndGetAsDocument(objectMapper, type), new UpdateOptions().upsert(upsert)); } else { return mongoCollection.updateMany(serializeQuery(query), update.serializeAndGetAsDocument(objectMapper, type), new UpdateOptions().upsert(upsert)); } } /** * Performs an update operation without upsert and default write concern. * * @param query * search query for old object to update * @param object * a document describing the update, which may not be null. The update to apply must include only update operators. * @return The result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult update(Document query, Document object) throws MongoException, MongoWriteException, MongoWriteConcernException { return updateOne(query, object, false, null); } /** * Performs an update operation. * * @param query * search query for old object to update * @param update * update with which to update <tt>query</tt> * @return The update result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult update(DBQuery.Query query, DBUpdate.Builder update) throws MongoException, MongoWriteException, MongoWriteConcernException { return this.updateOne(query, update, false, null); } /** * Performs an update operation. * * @param _id * The id of the document to update * @param update * update with which to update <tt>query</tt> * @return The write result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateById(Object _id, DBUpdate.Builder update) throws MongoException, MongoWriteException, MongoWriteConcernException { return this.update(createIdQuery(_id), update.serializeAndGetAsDocument(objectMapper, type)); } /** * Update all matching records * * @param query * search query for old object to update * @param object * object with which to update <tt>query</tt> * @return The result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateMany(Document query, Document object) throws MongoException, MongoWriteException, MongoWriteConcernException { return updateMany(query, object, false, null); } /** * Update all matching records * * @param query * search query for old object to update * @param update * update with which to update <tt>query</tt> * @return The write result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult updateMany(DBQuery.Query query, DBUpdate.Builder update) throws MongoException, MongoWriteException, MongoWriteConcernException { return updateMany(query, update, false, null); } /** * Performs an update operation, replacing the entire document. * * @param query * search query for old object to replace * @param object * object with which to replace <tt>query</tt> * @param upsert * if the database should create the element if it does not exist * @param concern * the write concern * @return The write result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult replaceOne(DBQuery.Query query, T object, boolean upsert, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { if (concern != null) { return mongoCollection.withWriteConcern(concern).replaceOne(serializeQuery(query), object, new ReplaceOptions().upsert(upsert)); } else { return mongoCollection.replaceOne(serializeQuery(query), object, new ReplaceOptions().upsert(upsert)); } } /** * Performs an update operation, replacing the entire document. * * @param query * search query for old object to replace * @param object * object with which to replace <tt>query</tt> * @param upsert * if the database should create the element if it does not exist * @param concern * the write concern * @return The write result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult replaceOne(Document query, T object, boolean upsert, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { query = serializeFields(query); if (concern != null) { return mongoCollection.withWriteConcern(concern).replaceOne(query, object, new ReplaceOptions().upsert(upsert)); } else { return mongoCollection.replaceOne(query, object, new ReplaceOptions().upsert(upsert)); } } /** * Performs an update operation, replacing the entire document. * * @param query * search query for old object to replace * @param object * object with which to replace <tt>query</tt> * @return The result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult replaceOne(DBQuery.Query query, T object) throws MongoException, MongoWriteException, MongoWriteConcernException { return replaceOne(query, object, false, null); } /** * Performs an update operation, replacing the entire document, for the document with this _id. * * @param _id * the _id of the object to replace * @param object * object with which to replace <tt>query</tt> * @return The result * @throws MongoWriteException * If the write failed due some other failure specific to the update command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult replaceOneById(Object _id, T object) throws MongoException, MongoWriteException, MongoWriteConcernException { return replaceOne(createIdQuery(_id), object, false, null); } /** * Removes objects from the database collection. * * @param query * the object that documents to be removed must match * @param concern * WriteConcern for this operation * @return The result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public DeleteResult remove(Document query, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { query = serializeFields(query); if (concern != null) { return mongoCollection.withWriteConcern(concern).deleteMany(query); } else { return mongoCollection.deleteMany(query); } } /** * Removes objects from the database collection. * * @param query * the query * @param concern * WriteConcern for this operation * @return The result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public DeleteResult remove(DBQuery.Query query, WriteConcern concern) throws MongoException, MongoWriteException, MongoWriteConcernException { if (concern != null) { return mongoCollection.withWriteConcern(concern).deleteMany(serializeQuery(query)); } else { return mongoCollection.deleteMany(serializeQuery(query)); } } /** * Removes objects from the database collection with the default WriteConcern * * @param query * the query that documents to be removed must match * @return The Delete result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public DeleteResult remove(Document query) throws MongoException, MongoWriteException, MongoWriteConcernException { return remove(query, null); } /** * Removes objects from the database collection with the default WriteConcern * * @param query * the query * @return The delete result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public DeleteResult remove(DBQuery.Query query) throws MongoException, MongoWriteException, MongoWriteConcernException { return remove(query, null); } /** * Removes object from the database collection with the default WriteConcern * * @param _id * the id of the document to remove * @return The delete result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public DeleteResult removeById(Object _id) throws MongoException, MongoWriteException, MongoWriteConcernException { return remove(createIdQuery(_id)); } /** * Finds the first document in the query and updates it. * * @param query * query to match * @param fields * fields to be returned * @param sort * sort to apply before picking first document * @param update * update to apply. This must contain only update operators * @param returnNew * if true, the updated document is returned, otherwise the old * document is returned (or it would be lost forever) * @param upsert * do upsert (insert if document not present) * @return the object */ public T findAndModify(Document query, Document fields, Document sort, Document update, boolean returnNew, boolean upsert) { return mongoCollection.findOneAndUpdate(serializeFields(query), update, new FindOneAndUpdateOptions() .returnDocument(returnNew ? ReturnDocument.AFTER : ReturnDocument.BEFORE).projection(fields) .sort(sort).upsert(upsert)); } /** * Finds the first document in the query and updates it. * * @param query * query to match * @param fields * fields to be returned * @param sort * sort to apply before picking first document * @param update * update to apply * @param returnNew * if true, the updated document is returned, otherwise the old * document is returned (or it would be lost forever) * @param upsert * do upsert (insert if document not present) * @return the object */ public T findAndModify(DBQuery.Query query, Document fields, Document sort, DBUpdate.Builder update, boolean returnNew, boolean upsert) { return mongoCollection.findOneAndUpdate(serializeQuery(query), update.serializeAndGetAsDocument(objectMapper, type), new FindOneAndUpdateOptions() .returnDocument(returnNew ? ReturnDocument.AFTER : ReturnDocument.BEFORE).projection(fields) .sort(sort).upsert(upsert)); } /** * Finds the first document in the query and updates it. * * @param query * query to match * @param fields * fields to be returned * @param sort * sort to apply before picking first document * @param update * update to apply * @param returnNew * if true, the updated document is returned, otherwise the old * document is returned (or it would be lost forever) * @param upsert * do upsert (insert if document not present) * @return the object */ public T findAndModify(Document query, Document fields, Document sort, DBUpdate.Builder update, boolean returnNew, boolean upsert) { return mongoCollection.findOneAndUpdate(serializeFields(query), update.serializeAndGetAsDocument(objectMapper, type), new FindOneAndUpdateOptions() .returnDocument(returnNew ? ReturnDocument.AFTER : ReturnDocument.BEFORE).projection(fields) .sort(sort).upsert(upsert)); } /** * Finds a document and deletes it. * * @param query * The query * @return the removed object */ public T findAndRemove(Document query) { return mongoCollection.findOneAndDelete(serializeFields(query)); } /** * Finds a document and deletes it. * * @param query * The query * @return the removed object */ public T findAndRemove(DBQuery.Query query) { return mongoCollection.findOneAndDelete(serializeQuery(query)); } /** * creates an index with default index options * * @param keys * an object with a key set of the fields desired for the index * @throws MongoException * If an error occurred */ public void createIndex(Document keys) throws MongoException { mongoCollection.createIndex(keys); } /** * Forces creation of an index on a set of fields, if one does not already * exist. * * @param keys * The keys to index * @param options * The options * @throws MongoException * If an error occurred */ public void createIndex(Document keys, IndexOptions options) throws MongoException { mongoCollection.createIndex(keys, options); } /** * Queries for an object in this collection. * * @param query * object for which to search * @return an iterator over the results * @throws MongoException * If an error occurred */ public FindIterable<T> find(DBQuery.Query query) throws MongoException { return mongoCollection.find(serializeQuery(query)); } /** * Queries for an object in this collection. * <p> * <p> * An empty DBObject will match every document in the collection. Regardless of fields specified, the _id fields are * always returned. * </p> * <p> * An example that returns the "x" and "_id" fields for every document in the collection that has an "x" field: * </p> * * <pre> * BasicDBObject keys = new BasicDBObject(); * keys.put("x", 1); * * DBCursor cursor = collection.find(new BasicDBObject(), keys); * </pre> * * @param query * object for which to search * @return a cursor to iterate over results */ public FindIterable<T> find(Document query) { return mongoCollection.find(serializeFields(query)); } /** * Queries for all objects in this collection. * * @return a cursor which will iterate over every object * @throws MongoException * If an error occurred */ public FindIterable<T> find() throws MongoException { return mongoCollection.find(); } /** * Returns a single object from this collection. * * @return the object found, or <code>null</code> if the collection is empty * @throws MongoException * If an error occurred */ public T findOne() throws MongoException { return findOne(new Document()); } /** * Find an object by the given id * * @param id * The id * @return The object * @throws MongoException * If an error occurred */ public T findOneById(Object id) throws MongoException { return findOne(createIdQuery(id)); } /** * Returns a single object from this collection matching the query. * * @param query * the query object * @return the object found, or <code>null</code> if no such object exists */ public T findOne(Document query) { return this.find(query).first(); } /** * Returns a single object from this collection matching the query. * * @param query * the query object * @return the object found, or <code>null</code> if no such object exists */ public T findOne(DBQuery.Query query) { return this.find(query).first(); } /** * Saves and object to this collection (does insert or update based on the object _id). Uses default write concern. * * @param object * the object to save. will add <code>_id</code> field to object if * needed * @return The UpdateResult result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult save(T object) throws MongoWriteException, MongoWriteConcernException, MongoException { return this.save(object, null); } /** * Saves an object to this collection (does insert or update based on the * object _id). * * @param object * the <code>DBObject</code> to save * @param concern * the write concern * @return The UpdateResult result * @throws MongoWriteException * If the write failed due some other failure specific to the delete command * @throws MongoWriteConcernException * If the write failed due being unable to fulfill the write concern * @throws MongoException * If an error occurred */ public UpdateResult save(T object, WriteConcern concern) throws MongoWriteException, MongoWriteConcernException, MongoException { Document dbObject = convertToDocument(object); Object _id = dbObject.get("_id"); if (_id == null) { this.insert(object, concern); return UpdateResult.acknowledged(0, 1L, new BsonObjectId((ObjectId) convertToDocument(object).get("_id"))); } else { return this.replaceOne(new Document("_id", _id), object, true, concern); } } /** * Drops all indices from this collection * * @throws MongoException * If an error occurred */ public void dropIndexes() throws MongoException { mongoCollection.dropIndexes(); } /** * Drops an index from this collection * * @param name * the index name * @throws MongoException * If an error occurred */ public void dropIndex(String name) throws MongoException { mongoCollection.dropIndex(name); } /** * Drops (deletes) this collection. Use with care. * * @throws MongoException * If an error occurred */ public void drop() throws MongoException { mongoCollection.drop(); } /** * Gets a count of documents in the collection * * @return number of documents that match query * @throws MongoException * If an error occurred */ public long count() throws MongoException { return getCount(new Document()); } /** * Gets a count of documents which match the query * * @param query * query to match * @return The count * @throws MongoException * If an error occurred */ public long getCount(Document query) throws MongoException { return mongoCollection.count(query); } /** * Gets a count of documents which match the query * * @param query * query to match * @return The count * @throws MongoException * If an error occurred */ public long getCount(DBQuery.Query query) throws MongoException { return mongoCollection.count(serializeQuery(query)); } /** * find distinct values for a key * * @param key * The key * @return The results */ public <ResultType> List<ResultType> distinct(String key, Class<ResultType> resultClass) { return mongoCollection.distinct(key, resultClass).into(new ArrayList<>()); } /** * find distinct values for a key * * @param key * The key * @param query * query to match * @return The results */ public <ResultType> List<ResultType> distinct(String key, Document query, Class<ResultType> resultClass) { return mongoCollection.distinct(key, serializeFields(query), resultClass).into(new ArrayList<>()); } /** * Performs a map reduce operation * * @param mapFunction - The map function to execute * @param reduceFunction - The reduce function to execute * @param resultClass - The class for the expected result type * @return MapReduceIterable of the resultClass * @throws MongoException */ public <ResultType> MapReduceIterable<ResultType> mapReduce(String mapFunction, String reduceFunction, Class<ResultType> resultClass) throws MongoException { return mongoCollection.mapReduce(mapFunction, reduceFunction, resultClass); } /** * Performs an aggregation pipeline against this collection. * * @param pipeline - This should be a List of Bson Documents in the Mongo aggregation language. * @param resultClass - The class for the type that will be returned * @return an AggregateIterable with the result objects mapped to the type specified by the resultClass. * @throws MongoException * If an error occurred * @see <a * href="http://www.mongodb.org/display/DOCS/Aggregation">http://www.mongodb.org/display/DOCS/Aggregation</a> * @since 2.1.0 */ public <ResultType> AggregateIterable<ResultType> aggregate(List<? extends Bson> pipeline, Class<ResultType> resultClass) throws MongoException { return mongoCollection.aggregate(pipeline, resultClass); } /** * * @param pipeline - This is a MongoJack Aggregation.Pipeline * @param resultClass - Class of the results from the aggregationt. * @return an AggregationIterable with result object mapped to the type specified by the resultClass. * @throws MongoException */ public <ResultType> AggregateIterable<ResultType> aggregate(Aggregation.Pipeline<?> pipeline, Class<ResultType> resultClass) throws MongoException { return mongoCollection.aggregate(serializePipeline(pipeline), resultClass); } /** * Set the write concern for this collection. Will be used for writes to * this collection. Overrides any setting of write concern at the DB level. * See the documentation for {@link WriteConcern} for more information. * * @param concern * write concern to use */ public void setWriteConcern(WriteConcern concern) { this.mongoCollection = mongoCollection.withWriteConcern(concern); } /** * Get the write concern for this collection. * * @return THe write concern */ public WriteConcern getWriteConcern() { return mongoCollection.getWriteConcern(); } /** * Sets the read preference for this collection. Will be used as default for * reads from this collection; overrides DB & Connection level settings. See * the * documentation for {@link ReadPreference} for more information. * * @param preference * Read Preference to use */ public void setReadPreference(ReadPreference preference) { this.mongoCollection = mongoCollection.withReadPreference(preference); } /** * Gets the read preference * * @return The read preference */ public ReadPreference getReadPreference() { return mongoCollection.getReadPreference(); } /** * Creates a document query object for the _id field using the object as the _id. This object is expected to already * be in the correct format... Document, Long, String, etc... * * @param _id * @return */ private Document createIdQuery(Object _id) { return new Document("_id", _id); } private Document convertToDocument(T object) throws MongoException { return convertToDocument(object, this.objectMapper, this.view); } /** * This method provides a static way to convert an object into a Document. Defaults will be used for all parameters * left null. * * @param object The object to convert * @param objectMapper The specific Jackson ObjectMapper to use. (Default MongoJack ObjectMapper) * @param view The Jackson View to use in serialization. (Default null) * @return */ public static <T> Document convertToDocument(T object, ObjectMapper objectMapper, Class<?> view) { if (object == null) { return null; } if (objectMapper == null) { objectMapper = DEFAULT_OBJECT_MAPPER; } DocumentObjectGenerator generator = new DocumentObjectGenerator(); try { objectMapper.writerWithView(view).writeValue(generator, object); } catch (JsonMappingException e) { throw new MongoJsonMappingException(e); } catch (IOException e) { // This shouldn't happen throw new MongoException("Unknown error occurred converting BSON to object", e); } return generator.getDocument(); } /** * Convert a Document, normally a query result to the object type for this * collection using the Jackson ObjectMapper for this collection. * * @param document The Document to convert * @return A converted instance of the object type of this class. * @throws MongoException */ private T convertFromDocument(Document document) throws MongoException { return convertFromDocument(document, this.valueClass, this.objectMapper, this.view); } /** * This method provides a static method to convert a DBObject into a given class. If the ObjectMapper is null, use a * default ObjectMapper * * @param document * @param clazz * @param objectMapper * @param view * @return * @throws MongoException */ public static <S> S convertFromDocument(Document document, Class<S> clazz, ObjectMapper objectMapper, Class<?> view) throws MongoException { if (document == null) { return null; } if (objectMapper == null) objectMapper = DEFAULT_OBJECT_MAPPER; try { return objectMapper.readerWithView(view) .readValue(new DocumentObjectTraversingParser(document, objectMapper), clazz); } catch (JsonMappingException e) { throw new MongoJsonMappingException(e); } catch (IOException e) { // This shouldn't happen throw new MongoException("Unknown error occurred converting BSON to object", e); } } /** * Serialize the fields of the given object using the object mapper * for this collection. * This will convert POJOs to DBObjects where necessary. * * @param value The object to serialize the fields of * @return The DBObject, safe for use in a mongo query. */ public Document serializeFields(Document value) { return DocumentSerializationUtils.serializeFields(objectMapper, value); } /** * Serialize the given DBQuery.Query using the object mapper * for this collection. * * @param query The DBQuery.Query to serialize. * @return The query as a serialized DBObject ready to pass to mongo. */ public Document serializeQuery(DBQuery.Query query) { return DocumentSerializationUtils.serializeQuery(objectMapper, type, query); } Object serializeQueryCondition(String key, QueryCondition condition) { return DocumentSerializationUtils.serializeQueryCondition(objectMapper, type, key, condition); } public List<Document> serializePipeline(Aggregation.Pipeline<?> pipeline) { return DocumentSerializationUtils.serializePipeline(objectMapper, type, pipeline); } ObjectMapper getObjectMapper() { return objectMapper; } /** * Creates builder to build {@link JacksonMongoCollection}. * @return created builder */ public static <T> JacksonMongoCollectionBuilder<T> builder() { return new JacksonMongoCollectionBuilder<T>(); } /** * Builder to build {@link JacksonMongoCollection}. */ public static final class JacksonMongoCollectionBuilder<T> { private ObjectMapper objectMapper; private Class<?> view; private JacksonMongoCollectionBuilder() { } public JacksonMongoCollectionBuilder<T> withObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; return this; } public JacksonMongoCollectionBuilder<T> withView(Class<?> view) { this.view = view; return this; } /** * Builds a {@link JacksonMongoCollection}. Required parameters are set here. * * @param mongoCollection - The MongoCollection that {@link JacksonMongoCollection} will wrap. * @param valueType - The type that this should serialize and deserialize to. * @return A new instance of a JacksonMongoCollection */ public JacksonMongoCollection<T> build(com.mongodb.client.MongoCollection<?> mongoCollection, Class<T> valueType) { return new JacksonMongoCollection<T>(mongoCollection, this.objectMapper, valueType, view); } } }