Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GORA-649 Replace usage of deprecated API of MongoDB driver #207

Merged
merged 9 commits into from
Mar 29, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@
*/
package org.apache.gora.mongodb.filters;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.gora.filter.*;
import org.apache.gora.mongodb.store.MongoMapping;
import org.apache.gora.mongodb.store.MongoStore;
import org.apache.gora.persistency.impl.PersistentBase;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import static com.mongodb.client.model.Filters.*;

public class DefaultFactory<K, T extends PersistentBase> extends
BaseFactory<K, T> {
Expand All @@ -45,8 +47,8 @@ public List<String> getSupportedFilters() {
}

@Override
public DBObject createFilter(final Filter<K, T> filter,
final MongoStore<K, T> store) {
public Bson createFilter(final Filter<K, T> filter,
final MongoStore<K, T> store) {

if (filter instanceof FilterList) {
FilterList<K, T> filterList = (FilterList<K, T>) filter;
Expand All @@ -64,19 +66,17 @@ public DBObject createFilter(final Filter<K, T> filter,
}
}

protected DBObject transformListFilter(final FilterList<K, T> filterList,
final MongoStore<K, T> store) {
BasicDBObject query = new BasicDBObject();
for (Filter<K, T> filter : filterList.getFilters()) {
boolean succeeded = getFilterUtil().setFilter(query, filter, store);
if (!succeeded) {
return null;
}
}
return query;
protected Bson transformListFilter(final FilterList<K, T> filterList,
final MongoStore<K, T> store) {
List<Bson> filters = filterList.getFilters().stream()
.map(filter -> getFilterUtil().setFilter(filter, store))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
return filters.isEmpty() ? new Document() : and(filters);
}

protected DBObject transformFieldFilter(
protected Bson transformFieldFilter(
final SingleFieldValueFilter<K, T> fieldFilter,
final MongoStore<K, T> store) {
MongoMapping mapping = store.getMapping();
Expand All @@ -85,17 +85,16 @@ protected DBObject transformFieldFilter(
FilterOp filterOp = fieldFilter.getFilterOp();
List<Object> operands = fieldFilter.getOperands();

QueryBuilder builder = QueryBuilder.start(dbFieldName);
builder = appendToBuilder(builder, filterOp, operands);
Bson filter = appendToBuilder(dbFieldName, filterOp, operands);
if (!fieldFilter.isFilterIfMissing()) {
// If false, the find query will pass if the column is not found.
DBObject notExist = QueryBuilder.start(dbFieldName).exists(false).get();
builder = QueryBuilder.start().or(notExist, builder.get());
Bson notExist = exists(dbFieldName, false);
filter = or(notExist, filter);
}
return builder.get();
return filter;
}

protected DBObject transformMapFilter(
protected Bson transformMapFilter(
final MapFieldValueFilter<K, T> mapFilter, final MongoStore<K, T> store) {
MongoMapping mapping = store.getMapping();
String dbFieldName = mapping.getDocumentField(mapFilter.getFieldName())
Expand All @@ -104,51 +103,43 @@ protected DBObject transformMapFilter(
FilterOp filterOp = mapFilter.getFilterOp();
List<Object> operands = mapFilter.getOperands();

QueryBuilder builder = QueryBuilder.start(dbFieldName);
builder = appendToBuilder(builder, filterOp, operands);
Bson filter = appendToBuilder(dbFieldName, filterOp, operands);
if (!mapFilter.isFilterIfMissing()) {
// If false, the find query will pass if the column is not found.
DBObject notExist = QueryBuilder.start(dbFieldName).exists(false).get();
builder = QueryBuilder.start().or(notExist, builder.get());
Bson notExist = exists(dbFieldName, false);
filter = or(notExist, filter);
}
return builder.get();
return filter;
}

protected QueryBuilder appendToBuilder(final QueryBuilder builder,
protected Bson appendToBuilder(final String dbFieldName,
final FilterOp filterOp, final List<Object> rawOperands) {
List<String> operands = convertOperandsToString(rawOperands);
switch (filterOp) {
case EQUALS:
if (operands.size() == 1) {
builder.is(operands.iterator().next());
return eq(dbFieldName, operands.iterator().next());
} else {
builder.in(operands);
return in(dbFieldName, operands);
}
break;
case NOT_EQUALS:
if (operands.size() == 1) {
builder.notEquals(operands.iterator().next());
return ne(dbFieldName, operands.iterator().next());
} else {
builder.notIn(operands);
return nin(dbFieldName, operands);
}
break;
case LESS:
builder.lessThan(operands);
break;
return lt(dbFieldName, operands);
case LESS_OR_EQUAL:
builder.lessThanEquals(operands);
break;
return lte(dbFieldName, operands);
case GREATER:
builder.greaterThan(operands);
break;
return gt(dbFieldName, operands);
case GREATER_OR_EQUAL:
builder.greaterThanEquals(operands);
break;
return gte(dbFieldName, operands);
default:
throw new IllegalArgumentException(filterOp
+ " no MongoDB equivalent yet");
}
return builder;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
*/
package org.apache.gora.mongodb.filters;

import java.util.List;

import org.apache.gora.filter.Filter;
import org.apache.gora.mongodb.store.MongoStore;
import org.apache.gora.persistency.impl.PersistentBase;
import org.bson.conversions.Bson;

import com.mongodb.DBObject;
import java.util.List;

/**
* Describe factory which create remote filter for MongoDB.
Expand All @@ -38,5 +37,5 @@ public interface FilterFactory<K, T extends PersistentBase> {

List<String> getSupportedFilters();

DBObject createFilter(Filter<K, T> filter, MongoStore<K, T> store);
Bson createFilter(Filter<K, T> filter, MongoStore<K, T> store);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
*/
package org.apache.gora.mongodb.filters;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.gora.filter.Filter;
Expand All @@ -28,8 +25,11 @@
import org.apache.gora.util.GoraException;
import org.apache.gora.util.ReflectionUtils;
import org.apache.hadoop.conf.Configuration;
import org.bson.conversions.Bson;

import com.mongodb.DBObject;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;

/**
* Manage creation of filtering {@link org.apache.gora.query.Query} using
Expand All @@ -40,8 +40,7 @@
* </p>
*
* @author Damien Raude-Morvan draudemorvan@dictanova.com
* @see #setFilter(com.mongodb.DBObject, org.apache.gora.filter.Filter,
* org.apache.gora.mongodb.store.MongoStore)
* @see #setFilter(Filter, MongoStore)
*/
public class MongoFilterUtil<K, T extends PersistentBase> {

Expand Down Expand Up @@ -87,32 +86,29 @@ public FilterFactory<K, T> getFactory(final Filter<K, T> filter) {
/**
* Set a filter on the <tt>query</tt>. It translates a Gora filter to a
* MongoDB filter.
*
* @param query
* The Mongo Query
*
* @param filter
* The Gora filter.
* @param store
* The MongoStore.
* @return if remote filter is successfully applied.
*/
public boolean setFilter(final DBObject query, final Filter<K, T> filter,
final MongoStore<K, T> store) {
public Optional<Bson> setFilter(final Filter<K, T> filter,
final MongoStore<K, T> store) {

FilterFactory<K, T> factory = getFactory(filter);
if (factory == null) {
LOG.warn("MongoDB remote filter factory not yet implemented for "
+ filter.getClass().getCanonicalName());
return false;
return Optional.empty();
} else {
DBObject mongoFilter = factory.createFilter(filter, store);
Bson mongoFilter = factory.createFilter(filter, store);
if (mongoFilter == null) {
LOG.warn("MongoDB remote filter not yet implemented for "
+ filter.getClass().getCanonicalName());
return false;
return Optional.empty();
} else {
query.putAll(mongoFilter);
return true;
return Optional.of(mongoFilter);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,24 @@
*/
package org.apache.gora.mongodb.query;

import com.mongodb.client.model.Projections;
import org.apache.gora.mongodb.store.MongoMapping;
import org.apache.gora.persistency.impl.PersistentBase;
import org.apache.gora.query.Query;
import org.apache.gora.query.impl.QueryBase;
import org.apache.gora.store.DataStore;
import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.gte;
import static com.mongodb.client.model.Filters.lte;

/**
* MongoDB specific implementation of the {@link Query} interface.
Expand All @@ -44,40 +54,37 @@ public MongoDBQuery(DataStore<K, T> dataStore) {
/**
* Compute the query itself. Only make use of the keys for querying.
*
* @return a {@link DBObject} corresponding to the query
* @return a {@link Document} corresponding to the query
*/
public static DBObject toDBQuery(Query<?, ?> query) {
BasicDBObject q = new BasicDBObject();
public static Bson toDBQuery(Query<?, ?> query) {

if ((query.getStartKey() != null) && (query.getEndKey() != null)
&& query.getStartKey().equals(query.getEndKey())) {
q.put("_id", query.getStartKey());
return eq("_id", query.getStartKey());
} else {
if (query.getStartKey() != null)
q.put("_id", new BasicDBObject("$gte", query.getStartKey()));
if (query.getEndKey() != null)
q.put("_id", new BasicDBObject("$lte", query.getEndKey()));
List<Bson> filters = new ArrayList<>();
if (query.getStartKey() != null) {
filters.add(gte("_id", query.getStartKey()));
}
if (query.getEndKey() != null) {
filters.add(lte("_id", query.getEndKey()));
}
return filters.isEmpty() ? new Document() : and(filters);
}

return q;
}

/**
* Compute the projection of the query, that is the fields that will be
* retrieved from the database.
*
* @return a {@link DBObject} corresponding to the list of field to be
* @return a {@link Document} corresponding to the list of field to be
* retrieved with the associated boolean
*/
public static DBObject toProjection(String[] fields, MongoMapping mapping) {
BasicDBObject proj = new BasicDBObject();

for (String k : fields) {
String dbFieldName = mapping.getDocumentField(k);
if (dbFieldName != null && dbFieldName.length() > 0) {
proj.put(dbFieldName, true);
}
}

return proj;
public static Bson toProjection(String[] fields, MongoMapping mapping) {
List<String> dbFields = Stream.of(fields)
.map(mapping::getDocumentField)
.filter(dbField -> dbField != null && !dbField.isEmpty())
.collect(Collectors.toList());
return Projections.include(dbFields);
}
}