com.landawn.abacus.util.MongoCollectionExecutor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of abacus-android Show documentation
Show all versions of abacus-android Show documentation
A general and simple library for Android
/*
* Copyright (C) 2015 HaiYang Li
*
* 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 com.landawn.abacus.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import com.landawn.abacus.DataSet;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.util.u.Nullable;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalBoolean;
import com.landawn.abacus.util.u.OptionalByte;
import com.landawn.abacus.util.u.OptionalChar;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalFloat;
import com.landawn.abacus.util.u.OptionalInt;
import com.landawn.abacus.util.u.OptionalLong;
import com.landawn.abacus.util.u.OptionalShort;
import com.landawn.abacus.util.function.Function;
import com.landawn.abacus.util.function.ToBooleanFunction;
import com.landawn.abacus.util.function.ToByteFunction;
import com.landawn.abacus.util.function.ToCharFunction;
import com.landawn.abacus.util.function.ToDoubleFunction;
import com.landawn.abacus.util.function.ToFloatFunction;
import com.landawn.abacus.util.function.ToIntFunction;
import com.landawn.abacus.util.function.ToLongFunction;
import com.landawn.abacus.util.function.ToShortFunction;
import com.landawn.abacus.util.stream.Stream;
import com.mongodb.BasicDBObject;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.CountOptions;
import com.mongodb.client.model.DeleteOptions;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.model.InsertOneModel;
import com.mongodb.client.model.InsertOneOptions;
import com.mongodb.client.model.Projections;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.model.WriteModel;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
/**
*
* @since 0.8
*
* @author Haiyang Li
*/
public final class MongoCollectionExecutor {
private static final String _$ = "$";
private static final String _$SET = "$set";
private static final String _$GROUP = "$group";
private static final String _$SUM = "$sum";
private static final String _COUNT = "count";
private final MongoCollection coll;
private final AsyncMongoCollectionExecutor asyncCollExecutor;
/**
* Call mongoDB.withCodecRegistry(CodecRegistries.fromRegistries(MongoClient.getDefaultCodecRegistry(), new GeneralCodecRegistry()));
to support the encode/decode for general type
* @param coll
*/
MongoCollectionExecutor(final MongoDB dbExecutor, final MongoCollection coll) {
this(dbExecutor, coll, new AsyncExecutor(64, 300, TimeUnit.SECONDS));
}
MongoCollectionExecutor(final MongoDB dbExecutor, final MongoCollection coll, final AsyncExecutor asyncExecutor) {
this.coll = coll;
this.asyncCollExecutor = new AsyncMongoCollectionExecutor(this, asyncExecutor);
}
public MongoCollection coll() {
return coll;
}
public AsyncMongoCollectionExecutor async() {
return asyncCollExecutor;
}
public boolean exists(final String objectId) {
return exists(createObjectId(objectId));
}
public boolean exists(final ObjectId objectId) {
return exists(createFilter(objectId));
}
public boolean exists(final Bson filter) {
return coll.count(filter, new CountOptions().limit(1)) > 0;
}
public long count() {
return coll.count();
}
public long count(final Bson filter) {
return coll.count(filter);
}
public long count(final Bson filter, final CountOptions options) {
if (options == null) {
return coll.count(filter);
} else {
return coll.count(filter, options);
}
}
public Optional get(final String objectId) {
return get(createObjectId(objectId));
}
public Optional get(final ObjectId objectId) {
return get(Document.class, objectId);
}
public Optional get(final Class targetClass, final String objectId) {
return get(targetClass, createObjectId(objectId));
}
public Optional get(final Class targetClass, final ObjectId objectId) {
return get(targetClass, objectId, null);
}
public Optional get(final Class targetClass, final String objectId, final Collection selectPropNames) {
return get(targetClass, createObjectId(objectId), selectPropNames);
}
public Optional get(final Class targetClass, final ObjectId objectId, final Collection selectPropNames) {
return findFirst(targetClass, selectPropNames, createFilter(objectId), null);
}
public Document gett(final String objectId) {
return gett(createObjectId(objectId));
}
public Document gett(final ObjectId objectId) {
return gett(Document.class, objectId);
}
public T gett(final Class targetClass, final String objectId) {
return gett(targetClass, createObjectId(objectId));
}
public T gett(final Class targetClass, final ObjectId objectId) {
return gett(targetClass, objectId, null);
}
public T gett(final Class targetClass, final String objectId, final Collection selectPropNames) {
return gett(targetClass, createObjectId(objectId), selectPropNames);
}
public T gett(final Class targetClass, final ObjectId objectId, final Collection selectPropNames) {
return findFirst(targetClass, selectPropNames, createFilter(objectId), null).orElse(null);
}
public Optional findFirst(final Bson filter) {
return findFirst(Document.class, filter);
}
public Optional findFirst(final Class targetClass, final Bson filter) {
return findFirst(targetClass, null, filter);
}
public Optional findFirst(final Class targetClass, final Collection selectPropNames, final Bson filter) {
return findFirst(targetClass, selectPropNames, filter, null);
}
public Optional findFirst(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort) {
final FindIterable findIterable = query(selectPropNames, filter, sort, 0, 1);
final T result = toEntity(targetClass, findIterable);
return result == null ? (Optional) Optional.empty() : Optional.of(result);
}
public Optional findFirst(final Class targetClass, final Bson filter, final Bson sort, final Bson projection) {
final FindIterable findIterable = query(filter, sort, projection, 0, 1);
final T result = toEntity(targetClass, findIterable);
return result == null ? (Optional) Optional.empty() : Optional.of(result);
}
public List list(final Bson filter) {
return list(Document.class, filter);
}
public List list(final Class targetClass, final Bson filter) {
return list(targetClass, null, filter);
}
public List list(final Class targetClass, final Collection selectPropNames, final Bson filter) {
return list(targetClass, selectPropNames, filter, 0, Integer.MAX_VALUE);
}
public List list(final Class targetClass, final Collection selectPropNames, final Bson filter, final int offset, final int count) {
return list(targetClass, selectPropNames, filter, null, offset, count);
}
public List list(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort) {
return list(targetClass, selectPropNames, filter, sort, 0, Integer.MAX_VALUE);
}
/**
*
* @param targetClass an entity class with getter/setter method, Map.class
or basic single value type(Primitive/String/Date...)
* @param selectPropNames
* @param filter
* @param sort
* @param offset
* @param count
* @return
*/
public List list(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort, final int offset,
final int count) {
final FindIterable findIterable = query(selectPropNames, filter, sort, offset, count);
return MongoDB.toList(targetClass, findIterable);
}
public List list(final Class targetClass, final Bson filter, final Bson sort, final Bson projection) {
return list(targetClass, filter, sort, projection, 0, Integer.MAX_VALUE);
}
/**
*
* @param targetClass an entity class with getter/setter method, Map.class
or basic single value type(Primitive/String/Date...)
* @param filter
* @param sort
* @param projection
* @param offset
* @param count
* @return
*/
public List list(final Class targetClass, final Bson filter, final Bson sort, final Bson projection, final int offset, final int count) {
final FindIterable findIterable = query(filter, sort, projection, offset, count);
return MongoDB.toList(targetClass, findIterable);
}
@Beta
public OptionalBoolean queryForBoolean(final String propName, final Bson filter) {
return queryForSingleResult(Boolean.class, propName, filter).mapToBoolean(ToBooleanFunction.UNBOX);
}
@Beta
public OptionalChar queryForChar(final String propName, final Bson filter) {
return queryForSingleResult(Character.class, propName, filter).mapToChar(ToCharFunction.UNBOX);
}
@Beta
public OptionalByte queryForByte(final String propName, final Bson filter) {
return queryForSingleResult(Byte.class, propName, filter).mapToByte(ToByteFunction.UNBOX);
}
@Beta
public OptionalShort queryForShort(final String propName, final Bson filter) {
return queryForSingleResult(Short.class, propName, filter).mapToShort(ToShortFunction.UNBOX);
}
@Beta
public OptionalInt queryForInt(final String propName, final Bson filter) {
return queryForSingleResult(Integer.class, propName, filter).mapToInt(ToIntFunction.UNBOX);
}
@Beta
public OptionalLong queryForLong(final String propName, final Bson filter) {
return queryForSingleResult(Long.class, propName, filter).mapToLong(ToLongFunction.UNBOX);
}
@Beta
public OptionalFloat queryForFloat(final String propName, final Bson filter) {
return queryForSingleResult(Float.class, propName, filter).mapToFloat(ToFloatFunction.UNBOX);
}
@Beta
public OptionalDouble queryForDouble(final String propName, final Bson filter) {
return queryForSingleResult(Double.class, propName, filter).mapToDouble(ToDoubleFunction.UNBOX);
}
@Beta
public Nullable queryForString(final String propName, final Bson filter) {
return queryForSingleResult(String.class, propName, filter);
}
@Beta
public Nullable queryForDate(final String propName, final Bson filter) {
return queryForSingleResult(Date.class, propName, filter);
}
public Nullable queryForDate(final Class targetClass, final String propName, final Bson filter) {
return queryForSingleResult(targetClass, propName, filter);
}
public Nullable queryForSingleResult(final Class targetClass, final String propName, final Bson filter) {
final FindIterable findIterable = query(N.asList(propName), filter, null, 0, 1);
Document doc = findIterable.first();
return N.isNullOrEmpty(doc) ? (Nullable) Nullable.empty() : Nullable.of(N.convert(doc.get(propName), targetClass));
}
private T toEntity(final Class targetClass, final FindIterable findIterable) {
final Document doc = findIterable.first();
return N.isNullOrEmpty(doc) ? null : MongoDB.toEntity(targetClass, doc);
}
public DataSet query(final Bson filter) {
return query(Document.class, filter);
}
public DataSet query(final Class targetClass, final Bson filter) {
return query(targetClass, null, filter);
}
public DataSet query(final Class targetClass, final Collection selectPropNames, final Bson filter) {
return query(targetClass, selectPropNames, filter, 0, Integer.MAX_VALUE);
}
public DataSet query(final Class targetClass, final Collection selectPropNames, final Bson filter, final int offset, final int count) {
return query(targetClass, selectPropNames, filter, null, offset, count);
}
public DataSet query(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort) {
return query(targetClass, selectPropNames, filter, sort, 0, Integer.MAX_VALUE);
}
public DataSet query(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort, final int offset,
final int count) {
final FindIterable findIterable = query(selectPropNames, filter, sort, offset, count);
if (N.isNullOrEmpty(selectPropNames)) {
return MongoDB.extractData(targetClass, findIterable);
} else {
return MongoDB.extractData(targetClass, selectPropNames, findIterable);
}
}
public DataSet query(final Class targetClass, final Bson filter, final Bson sort, final Bson projection) {
return query(targetClass, filter, sort, projection, 0, Integer.MAX_VALUE);
}
public DataSet query(final Class targetClass, final Bson filter, final Bson sort, final Bson projection, final int offset, final int count) {
final FindIterable findIterable = query(filter, sort, projection, offset, count);
return MongoDB.extractData(targetClass, findIterable);
}
public Stream stream(final Bson filter) {
return stream(Document.class, filter);
}
public Stream stream(final Class targetClass, final Bson filter) {
return stream(targetClass, null, filter);
}
public Stream stream(final Class targetClass, final Collection selectPropNames, final Bson filter) {
return stream(targetClass, selectPropNames, filter, 0, Integer.MAX_VALUE);
}
public Stream stream(final Class targetClass, final Collection selectPropNames, final Bson filter, final int offset, final int count) {
return stream(targetClass, selectPropNames, filter, null, offset, count);
}
public Stream stream(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort) {
return stream(targetClass, selectPropNames, filter, sort, 0, Integer.MAX_VALUE);
}
public Stream stream(final Class targetClass, final Collection selectPropNames, final Bson filter, final Bson sort, final int offset,
final int count) {
final FindIterable findIterable = query(selectPropNames, filter, sort, offset, count);
if (targetClass.isAssignableFrom(Document.class)) {
return (Stream) Stream.of(findIterable.iterator());
} else {
return Stream.of(findIterable.iterator()).map(toEntity(targetClass));
}
}
public Stream stream(final Class targetClass, final Bson filter, final Bson sort, final Bson projection) {
return stream(targetClass, filter, sort, projection, 0, Integer.MAX_VALUE);
}
public Stream stream(final Class targetClass, final Bson filter, final Bson sort, final Bson projection, final int offset, final int count) {
final FindIterable findIterable = query(filter, sort, projection, offset, count);
if (targetClass.isAssignableFrom(Document.class)) {
return (Stream) Stream.of(findIterable.iterator());
} else {
return Stream.of(findIterable.iterator()).map(toEntity(targetClass));
}
}
private Function toEntity(final Class targetClass) {
return new Function() {
@Override
public T apply(Document t) {
return MongoDB.toEntity(targetClass, t);
}
};
}
private FindIterable query(final Collection selectPropNames, final Bson filter, final Bson sort, final int offset, final int count) {
if (N.isNullOrEmpty(selectPropNames)) {
return this.query(filter, sort, null, offset, count);
} else if (selectPropNames instanceof List) {
return this.query(filter, sort, Projections.include((List) selectPropNames), offset, count);
} else {
return this.query(filter, sort, Projections.include(selectPropNames.toArray(new String[selectPropNames.size()])), offset, count);
}
}
private FindIterable query(final Bson filter, final Bson sort, final Bson projection, final int offset, final int count) {
if (offset < 0 || count < 0) {
throw new IllegalArgumentException("offset (" + offset + ") and count(" + count + ") can't be negative");
}
FindIterable findIterable = coll.find(filter);
if (projection != null) {
findIterable = findIterable.projection(projection);
}
if (sort != null) {
findIterable = findIterable.sort(sort);
}
if (offset > 0) {
findIterable = findIterable.skip(offset);
}
if (count < Integer.MAX_VALUE) {
findIterable = findIterable.limit(count);
}
return findIterable;
}
/**
*
* @param obj can be Document/Map/entity
class with getter/setter method.
*/
public void insert(final Object obj) {
coll.insertOne(createDocument(obj));
}
public void insert(final Object obj, final InsertOneOptions options) {
coll.insertOne(createDocument(obj), options);
}
/**
*
* @param objList list of Document/Map/entity
class with getter/setter method.
*/
public void insertAll(final Collection> objList) {
insertAll(objList, null);
}
/**
*
* @param objList list of Document/Map/entity
class with getter/setter method.
* @param options
*/
public void insertAll(final Collection> objList, final InsertManyOptions options) {
List docs = null;
if (objList.iterator().next() instanceof Document) {
if (objList instanceof List) {
docs = (List) objList;
} else {
docs = new ArrayList<>((Collection) objList);
}
} else {
docs = new ArrayList<>(objList.size());
for (Object entity : objList) {
docs.add(createDocument(entity));
}
}
if (options == null) {
coll.insertMany(docs);
} else {
coll.insertMany(docs, options);
}
}
/**
* Update the record in data store with the properties which have been updated/set in the specified update
by the specified objectId
.
* if the update
implements DirtyMarker
interface, just update the dirty properties.
*
* @param objectId
* @param update can be Bson/Document/Map/entity class with getter/setter method.
* @return
*/
public UpdateResult update(final String objectId, final Object update) {
return update(createObjectId(objectId), update);
}
/**
* Update the record in data store with the properties which have been updated/set in the specified update
by the specified objectId
.
* if the update
implements DirtyMarker
interface, just update the dirty properties.
*
* @param objectId
* @param update can be Bson/Document/Map/entity class with getter/setter method.
* @return
*/
public UpdateResult update(final ObjectId objectId, final Object update) {
return updateOne(createFilter(objectId), update);
}
/**
* Just update one record in data store with the properties which have been updated/set in the specified update
by the specified filter
.
* if the update
implements DirtyMarker
interface, just update the dirty properties.
*
* @param filter
* @param update can be Bson/Document/Map/entity class with getter/setter method.
* @return
*/
public UpdateResult updateOne(final Bson filter, final Object update) {
return updateOne(filter, update, null);
}
/**
* Just update one record in data store with the properties which have been updated/set in the specified update
by the specified filter
.
* if the update
implements DirtyMarker
interface, just update the dirty properties.
*
* @param filter
* @param update can be Bson/Document/Map/entity class with getter/setter method.
* @param options
* @return
*/
public UpdateResult updateOne(final Bson filter, final Object update, final UpdateOptions options) {
if (options == null) {
return coll.updateOne(filter, checkUpdate(update));
} else {
return coll.updateOne(filter, checkUpdate(update), options);
}
}
/**
* Update the records in data store with the properties which have been updated/set in the specified update
by the specified filter
.
* if the update
implements DirtyMarker
interface, just update the dirty properties.
*
* @param filter
* @param update can be Bson/Document/Map/entity class with getter/setter method.
* @return
*/
public UpdateResult updateAll(final Bson filter, final Object update) {
return updateAll(filter, update, null);
}
/**
* Update the records in data store with the properties which have been updated/set in the specified update
by the specified filter
.
* if the update
implements DirtyMarker
interface, just update the dirty properties.
*
* @param filter
* @param update can be Bson/Document/Map/entity class with getter/setter method.
* @param options
* @return
*/
public UpdateResult updateAll(final Bson filter, final Object update, final UpdateOptions options) {
if (options == null) {
return coll.updateMany(filter, checkUpdate(update));
} else {
return coll.updateMany(filter, checkUpdate(update), options);
}
}
/**
*
* @param objectId
* @param replacement can be Document/Map/entity
class with getter/setter method.
* @return
*/
public UpdateResult replace(final String objectId, final Object replacement) {
return replace(createObjectId(objectId), replacement);
}
/**
*
* @param objectId
* @param replacement can be Document/Map/entity
class with getter/setter method.
* @return
*/
public UpdateResult replace(final ObjectId objectId, final Object replacement) {
return replaceOne(createFilter(objectId), replacement);
}
/**
*
* @param filter
* @param replacement can be Document/Map/entity
class with getter/setter method.
* @return
*/
public UpdateResult replaceOne(final Bson filter, final Object replacement) {
return replaceOne(filter, replacement, null);
}
/**
*
* @param filter
* @param replacement can be Document/Map/entity
class with getter/setter method.
* @param options
* @return
*/
public UpdateResult replaceOne(final Bson filter, final Object replacement, final UpdateOptions options) {
if (options == null) {
return coll.replaceOne(filter, createDocument(replacement));
} else {
return coll.replaceOne(filter, createDocument(replacement), options);
}
}
public DeleteResult delete(final String objectId) {
return delete(createObjectId(objectId));
}
public DeleteResult delete(final ObjectId objectId) {
return deleteOne(createFilter(objectId));
}
public DeleteResult deleteOne(final Bson filter) {
return coll.deleteOne(filter);
}
public DeleteResult deleteOne(final Bson filter, final DeleteOptions options) {
return coll.deleteOne(filter, options);
}
public DeleteResult deleteAll(final Bson filter) {
return coll.deleteMany(filter);
}
public DeleteResult deleteAll(final Bson filter, final DeleteOptions options) {
return coll.deleteMany(filter, options);
}
public int bulkInsert(final Collection> entities) {
return bulkInsert(entities, null);
}
public int bulkInsert(final Collection> entities, final BulkWriteOptions options) {
final List> list = new ArrayList<>(entities.size());
for (Object entity : entities) {
if (entity instanceof Document) {
list.add(new InsertOneModel((Document) entity));
} else {
list.add(new InsertOneModel(MongoDB.toDocument(entity)));
}
}
return bulkWrite(list, options).getInsertedCount();
}
public BulkWriteResult bulkWrite(final List extends WriteModel extends Document>> requests) {
return bulkWrite(requests, null);
}
public BulkWriteResult bulkWrite(final List extends WriteModel extends Document>> requests, final BulkWriteOptions options) {
if (options == null) {
return coll.bulkWrite(requests);
} else {
return coll.bulkWrite(requests, options);
}
}
public Stream distinct(final Class targetClass, final String fieldName) {
return Stream.of(coll.distinct(fieldName, targetClass).iterator());
}
public Stream distinct(final Class targetClass, final String fieldName, final Bson filter) {
return Stream.of(coll.distinct(fieldName, filter, targetClass).iterator());
}
public Stream aggregate(final List extends Bson> pipeline) {
return aggregate(Document.class, pipeline);
}
public Stream aggregate(final Class targetClass, final List extends Bson> pipeline) {
return Stream.of(coll.aggregate(pipeline, Document.class).iterator()).map(toEntity(targetClass));
}
public Stream mapReduce(final String mapFunction, final String reduceFunction) {
return mapReduce(Document.class, mapFunction, reduceFunction);
}
public Stream mapReduce(final Class targetClass, final String mapFunction, final String reduceFunction) {
return Stream.of(coll.mapReduce(mapFunction, reduceFunction, Document.class).iterator()).map(toEntity(targetClass));
}
@Beta
public Stream groupBy(final String fieldName) {
return aggregate(N.asList(new Document(_$GROUP, new Document(MongoDB._ID, _$ + fieldName))));
}
@Beta
public Stream groupBy(final Collection fieldNames) {
final Document groupFields = new Document();
for (String fieldName : fieldNames) {
groupFields.put(fieldName, _$ + fieldName);
}
return aggregate(N.asList(new Document(_$GROUP, new Document(MongoDB._ID, groupFields))));
}
@Beta
public Stream groupByAndCount(final String fieldName) {
return aggregate(N.asList(new Document(_$GROUP, new Document(MongoDB._ID, _$ + fieldName).append(_COUNT, new Document(_$SUM, 1)))));
}
@Beta
public Stream groupByAndCount(final Collection fieldNames) {
final Document groupFields = new Document();
for (String fieldName : fieldNames) {
groupFields.put(fieldName, _$ + fieldName);
}
return aggregate(N.asList(new Document(_$GROUP, new Document(MongoDB._ID, groupFields).append(_COUNT, new Document(_$SUM, 1)))));
}
//
// private String getCollectionName(final Class> cls) {
// final String collectionName = classCollectionMapper.get(cls);
//
// if (N.isNullOrEmpty(collectionName)) {
// throw new IllegalArgumentException("No collection is mapped to class: " + cls);
// }
// return collectionName;
// }
//
// private String getObjectId(Object obj) {
// String objectId = null;
//
// try {
// objectId = N.convert(String.class, N.getPropValue(obj, "id"));
// } catch (Exception e) {
// // ignore
//
// try {
// objectId = N.convert(String.class, N.getPropValue(obj, "objectId"));
// } catch (Exception e2) {
// // ignore
// }
// }
//
// if (N.isNullOrEmpty(objectId)) {
// throw new IllegalArgumentException("Property value of 'id' or 'objectId' can't be null or empty for update or delete");
// }
//
// return objectId;
// }
//
private Bson checkUpdate(final Object update) {
Bson bson = update instanceof Bson ? (Bson) update : MongoDB.toDocument(update, true);
if (bson instanceof Document) {
Document doc = (Document) bson;
if (doc.size() > 0 && doc.keySet().iterator().next().startsWith(_$)) {
return doc;
}
} else if (bson instanceof BasicDBObject) {
BasicDBObject dbObject = (BasicDBObject) bson;
if (dbObject.size() > 0 && dbObject.keySet().iterator().next().startsWith(_$)) {
return dbObject;
}
}
return new Document(_$SET, bson);
}
private ObjectId createObjectId(final String objectId) {
if (N.isNullOrEmpty(objectId)) {
throw new IllegalArgumentException("Object id cant' be null or empty");
}
return new ObjectId(objectId);
}
private Bson createFilter(final ObjectId objectId) {
return new Document(MongoDB._ID, objectId);
}
private Document createDocument(final Object obj) {
return obj instanceof Document ? (Document) obj : MongoDB.toDocument(obj);
}
}