private object ExecuteMapReduce(MongoQueryObject queryObject)
        {
            var options = new MapReduceOptionsBuilder();

            options.SetQuery(new QueryDocument(queryObject.Query));
            options.SetFinalize(new BsonJavaScript(queryObject.FinalizerFunction));
            options.SetLimit(queryObject.NumberToLimit);

            if (queryObject.Sort != null)
            {
                options.SetSortOrder(new SortByDocument(queryObject.Sort));
            }

            if (queryObject.NumberToSkip != 0)
            {
                throw new InvalidQueryException("MapReduce queries do not support Skips.");
            }

            var mapReduce = _collection.MapReduce(
                new BsonJavaScript(queryObject.MapFunction),
                new BsonJavaScript(queryObject.ReduceFunction),
                options);

            var executor = GetExecutor(typeof(BsonDocument), queryObject.Projector, queryObject.Aggregator, true);

            return(executor.Compile().DynamicInvoke(queryObject.Collection.Database[mapReduce.CollectionName].FindAll()));
        }
        /// <summary>
        /// Executes the count.
        /// </summary>
        /// <param name="queryObject">The query object.</param>
        /// <returns></returns>
        private object ExecuteCount(MongoQueryObject queryObject)
        {
            if (queryObject.Query == null)
            {
                return((int)_collection.Count());
            }

            return((int)_collection.Count(new QueryDocument(queryObject.Query)));
        }
 /// <summary>
 /// Executes the query object.
 /// </summary>
 /// <param name="queryObject">The query object.</param>
 /// <returns></returns>
 internal object ExecuteQueryObject(MongoQueryObject queryObject)
 {
     if (queryObject.IsCount)
     {
         return(ExecuteCount(queryObject));
     }
     if (queryObject.IsMapReduce)
     {
         return(ExecuteMapReduce(queryObject));
     }
     return(ExecuteFind(queryObject));
 }
        private object ExecuteFind(MongoQueryObject queryObject)
        {
            var findAsMethod = typeof(MongoCollection).GetGenericMethod(
                "FindAs",
                BindingFlags.Public | BindingFlags.Instance,
                new[] { queryObject.DocumentType },
                new[] { typeof(IMongoQuery) });

            QueryDocument queryDocument;

            if (queryObject.Sort != null)
            {
                queryDocument = new QueryDocument
                {
                    { "query", queryObject.Query },
                    { "orderby", queryObject.Sort }
                };
            }
            else
            {
                queryDocument = new QueryDocument(queryObject.Query);
            }

            var cursor     = findAsMethod.Invoke(_collection, new[] { queryDocument });
            var cursorType = cursor.GetType();

            if (queryObject.Fields.ElementCount > 0)
            {
                var setFieldsMethod = cursorType.GetMethod(
                    "SetFields",
                    BindingFlags.Public | BindingFlags.Instance,
                    null,
                    new[] { typeof(IMongoFields) },
                    null
                    );

                setFieldsMethod.Invoke(cursor, new[] { new FieldsDocument(queryObject.Fields) });
            }

            var setLimitMethod = cursorType.GetMethod(
                "SetLimit",
                BindingFlags.Public | BindingFlags.Instance,
                null,
                new[] { typeof(int) },
                null);

            setLimitMethod.Invoke(cursor, new object[] { queryObject.NumberToLimit });

            var setSkipMethod = cursorType.GetMethod(
                "SetSkip",
                BindingFlags.Public | BindingFlags.Instance,
                null,
                new[] { typeof(int) },
                null);

            setSkipMethod.Invoke(cursor, new object[] { queryObject.NumberToSkip });

            var executor = GetExecutor(queryObject.DocumentType, queryObject.Projector, queryObject.Aggregator, true);

            return(executor.Compile().DynamicInvoke(cursor));
        }