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

com.mongodb.async.client.MapReduceIterableImpl Maven / Gradle / Ivy

There is a newer version: 3.12.14
Show newest version
/*
 * Copyright 2015-2016 MongoDB, Inc.
 *
 * 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.mongodb.async.client;

import com.mongodb.MongoNamespace;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
import com.mongodb.async.AsyncBatchCursor;
import com.mongodb.async.SingleResultCallback;
import com.mongodb.binding.AsyncReadBinding;
import com.mongodb.binding.AsyncWriteBinding;
import com.mongodb.client.model.Collation;
import com.mongodb.client.model.MapReduceAction;
import com.mongodb.operation.AsyncOperationExecutor;
import com.mongodb.operation.AsyncReadOperation;
import com.mongodb.operation.AsyncWriteOperation;
import com.mongodb.operation.FindOperation;
import com.mongodb.operation.MapReduceAsyncBatchCursor;
import com.mongodb.operation.MapReduceStatistics;
import com.mongodb.operation.MapReduceToCollectionOperation;
import com.mongodb.operation.MapReduceWithInlineResultsOperation;
import com.mongodb.session.ClientSession;
import org.bson.BsonJavaScript;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;

import java.util.concurrent.TimeUnit;

import static com.mongodb.ReadPreference.primary;
import static com.mongodb.assertions.Assertions.notNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

class MapReduceIterableImpl  extends MongoIterableImpl implements MapReduceIterable {
    private final MongoNamespace namespace;
    private final Class documentClass;
    private final Class resultClass;
    private final CodecRegistry codecRegistry;
    private final WriteConcern writeConcern;
    private final String mapFunction;
    private final String reduceFunction;

    private boolean inline = true;
    private String collectionName;
    private String finalizeFunction;
    private Bson scope;
    private Bson filter;
    private Bson sort;
    private int limit;
    private boolean jsMode;
    private boolean verbose = true;
    private long maxTimeMS;
    private MapReduceAction action = MapReduceAction.REPLACE;
    private String databaseName;
    private boolean sharded;
    private boolean nonAtomic;
    private Boolean bypassDocumentValidation;
    private Collation collation;

    MapReduceIterableImpl(final ClientSession clientSession, final MongoNamespace namespace, final Class documentClass,
                          final Class resultClass, final CodecRegistry codecRegistry, final ReadPreference readPreference,
                          final ReadConcern readConcern, final WriteConcern writeConcern, final AsyncOperationExecutor executor,
                          final String mapFunction, final String reduceFunction) {
        super(clientSession, executor, readConcern, readPreference);
        this.namespace = notNull("namespace", namespace);
        this.documentClass = notNull("documentClass", documentClass);
        this.resultClass = notNull("resultClass", resultClass);
        this.codecRegistry = notNull("codecRegistry", codecRegistry);
        this.writeConcern = notNull("writeConcern", writeConcern);
        this.mapFunction = notNull("mapFunction", mapFunction);
        this.reduceFunction = notNull("reduceFunction", reduceFunction);
    }

    @Override
    public MapReduceIterable collectionName(final String collectionName) {
        this.collectionName = notNull("collectionName", collectionName);
        this.inline = false;
        return this;
    }

    @Override
    public MapReduceIterable finalizeFunction(final String finalizeFunction) {
        this.finalizeFunction = finalizeFunction;
        return this;
    }

    @Override
    public MapReduceIterable scope(final Bson scope) {
        this.scope = scope;
        return this;
    }

    @Override
    public MapReduceIterable sort(final Bson sort) {
        this.sort = sort;
        return this;
    }

    @Override
    public MapReduceIterable filter(final Bson filter) {
        this.filter = filter;
        return this;
    }

    @Override
    public MapReduceIterable limit(final int limit) {
        this.limit = limit;
        return this;
    }

    @Override
    public MapReduceIterable jsMode(final boolean jsMode) {
        this.jsMode = jsMode;
        return this;
    }

    @Override
    public MapReduceIterable verbose(final boolean verbose) {
        this.verbose = verbose;
        return this;
    }

    @Override
    public MapReduceIterable maxTime(final long maxTime, final TimeUnit timeUnit) {
        notNull("timeUnit", timeUnit);
        this.maxTimeMS = TimeUnit.MILLISECONDS.convert(maxTime, timeUnit);
        return this;
    }

    @Override
    public MapReduceIterable action(final MapReduceAction action) {
        this.action = action;
        return this;
    }

    @Override
    public MapReduceIterable databaseName(final String databaseName) {
        this.databaseName = databaseName;
        return this;
    }

    @Override
    public MapReduceIterable sharded(final boolean sharded) {
        this.sharded = sharded;
        return this;
    }

    @Override
    public MapReduceIterable nonAtomic(final boolean nonAtomic) {
        this.nonAtomic = nonAtomic;
        return this;
    }

    @Override
    public MapReduceIterable batchSize(final int batchSize) {
        super.batchSize(batchSize);
        return this;
    }

    @Override
    public MapReduceIterable bypassDocumentValidation(final Boolean bypassDocumentValidation) {
        this.bypassDocumentValidation = bypassDocumentValidation;
        return this;
    }

    @Override
    public MapReduceIterable collation(final Collation collation) {
        this.collation = collation;
        return this;
    }

    @Override
    public void toCollection(final SingleResultCallback callback) {
        notNull("callback", callback);
        if (inline) {
            throw new IllegalStateException("The options must specify a non-inline result");
        }
        getExecutor().execute(createMapReduceToCollectionOperation(), callback);
    }

    @Override
    ReadPreference getReadPreference() {
        if (inline) {
            return super.getReadPreference();
        } else {
            return primary();
        }
    }

    @Override
    AsyncReadOperation> asAsyncReadOperation() {
        if (inline) {
            return createMapReduceInlineOperation();
        } else {
            return new AggregateToCollectionThenFindOperation(createMapReduceToCollectionOperation(), createFindOperation());
        }
    }

    private WrappedMapReduceReadOperation createMapReduceInlineOperation() {
        final MapReduceWithInlineResultsOperation operation = new MapReduceWithInlineResultsOperation(namespace,
                new BsonJavaScript(mapFunction), new BsonJavaScript(reduceFunction), codecRegistry.get(resultClass))
                .filter(toBsonDocumentOrNull(filter, documentClass, codecRegistry))
                .limit(limit)
                .maxTime(maxTimeMS, MILLISECONDS)
                .jsMode(jsMode)
                .scope(toBsonDocumentOrNull(scope, documentClass, codecRegistry))
                .sort(toBsonDocumentOrNull(sort, documentClass, codecRegistry))
                .verbose(verbose)
                .readConcern(getReadConcern())
                .collation(collation);
        if (finalizeFunction != null) {
            operation.finalizeFunction(new BsonJavaScript(finalizeFunction));
        }
        return new WrappedMapReduceReadOperation(operation);
    }

    private WrappedMapReduceWriteOperation createMapReduceToCollectionOperation() {
        MapReduceToCollectionOperation operation = new MapReduceToCollectionOperation(namespace, new BsonJavaScript(mapFunction),
                new BsonJavaScript(reduceFunction), collectionName, writeConcern)
                .filter(toBsonDocumentOrNull(filter, documentClass, codecRegistry))
                .limit(limit)
                .maxTime(maxTimeMS, MILLISECONDS)
                .jsMode(jsMode)
                .scope(toBsonDocumentOrNull(scope, documentClass, codecRegistry))
                .sort(toBsonDocumentOrNull(sort, documentClass, codecRegistry))
                .verbose(verbose)
                .action(action.getValue())
                .nonAtomic(nonAtomic)
                .sharded(sharded)
                .databaseName(databaseName)
                .bypassDocumentValidation(bypassDocumentValidation)
                .collation(collation);

        if (finalizeFunction != null) {
            operation.finalizeFunction(new BsonJavaScript(finalizeFunction));
        }
        return new WrappedMapReduceWriteOperation(operation);
    }

    private FindOperation createFindOperation() {
        String dbName = databaseName != null ? databaseName : namespace.getDatabaseName();
        return new FindOperation(new MongoNamespace(dbName, collectionName), codecRegistry.get(resultClass))
                .collation(collation)
                .batchSize(getBatchSize() == null ? 0 : getBatchSize());
    }

    // this could be inlined, but giving it a name so that it's unit-testable
    static class WrappedMapReduceReadOperation implements AsyncReadOperation> {
        private final AsyncReadOperation> operation;

        AsyncReadOperation> getOperation() {
            return operation;
        }

        WrappedMapReduceReadOperation(final MapReduceWithInlineResultsOperation operation) {
            this.operation = operation;
        }

        @Override
        public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback> callback) {
            operation.executeAsync(binding, new SingleResultCallback>() {
                @Override
                public void onResult(final MapReduceAsyncBatchCursor batchCursor, final Throwable t) {
                    callback.onResult(batchCursor, t);
                }
            });
        }
    }

    static class WrappedMapReduceWriteOperation implements AsyncWriteOperation {
        private final AsyncWriteOperation operation;

        AsyncWriteOperation  getOperation() {
            return operation;
        }

        WrappedMapReduceWriteOperation(final MapReduceToCollectionOperation operation) {
            this.operation = operation;
        }

        @Override
        public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback callback) {
            operation.executeAsync(binding, new SingleResultCallback() {
                @Override
                public void onResult(final MapReduceStatistics result, final Throwable t) {
                    callback.onResult(null, t);
                }
            });
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy