示例#1
0
        private IEnumerable <BsonValue> CollectForeignKeys(List <BsonValue> keys, string resource, string foreignkey)
        {
            IMongoQuery query = Query.And(Query.EQ(InternalField.RESOURCE, resource), Query.In(InternalField.ID, keys));
            MongoCursor <BsonDocument> cursor = collection.Find(query).SetFields(foreignkey);

            return(cursor.Select(doc => doc.GetValue(foreignkey)));
        }
示例#2
0
        public IEnumerable <T> Find <T>(string collectionName, string query, string fields, string sort, int skip, int limit)
        {
            RegisterClassForBSONSerialisation <T>();
            MongoCursor <BsonDocument> cursor = Find(collectionName, query, fields, sort, skip, limit);

            return(cursor.Select(DeserializeRetrieved <T>));
        }
 /// <summary>
 /// Splits a collection of objects into n pages with an (for example, if I have a list of 45 shoes and say 'shoes.Split(5)' I will now have 4 pages of 10 shoes and 1 page of 5 shoes.
 /// </summary>
 /// <typeparam name="T">The type of object the collection should contain.</typeparam>
 /// <param name="superset">The collection of objects to be divided into subsets.</param>
 /// <param name="numberOfPages">The number of pages this collection should be split into.</param>
 /// <returns>A subset of this collection of objects, split into n pages.</returns>
 public static IEnumerable <IEnumerable <T> > Split <T>(this MongoCursor <T> superset, int numberOfPages)
 {
     return(superset
            .Select((item, index) => new { index, item })
            .GroupBy(x => x.index % numberOfPages)
            .Select(x => x.Select(y => y.item)));
 }
示例#4
0
        public IList <string> FetchPrimaryKeys(IMongoQuery query)
        {
            MongoCursor <BsonDocument> cursor = collection.Find(query);

            cursor = cursor.SetFields(MonQ.Fields.Include(Field.PRIMARYKEY));

            return(cursor.Select(doc => doc.GetValue(Field.PRIMARYKEY).AsString).ToList());
        }
示例#5
0
        public IEnumerable <Uri> FetchKeys(IMongoQuery query)
        {
            MongoCursor <BsonDocument> cursor = collection.Find(query);

            cursor = cursor.SetFields(MonQ.Fields.Include(Field.VERSIONID));

            return(cursor.Select(doc => doc.GetValue(Field.VERSIONID).AsString).Select(s => new Uri(s, UriKind.Relative)));
        }
示例#6
0
        public IList <string> FetchPrimaryKeys(IMongoQuery query)
        {
            MongoCursor <BsonDocument> cursor = collection.Find(query)
                                                .SetSortOrder(MongoDB.Driver.Builders.SortBy.Descending(Field.WHEN));

            cursor = cursor.SetFields(MongoDB.Driver.Builders.Fields.Include(Field.PRIMARYKEY));

            return(cursor.Select(doc => doc.GetValue(Field.PRIMARYKEY).AsString).ToList());
        }
示例#7
0
        private List <BsonValue> CollectKeys(IMongoQuery query)
        {
            MongoCursor <BsonDocument> cursor = _collection.Find(query).SetFields(InternalField.ID);

            if (cursor.Count() > 0)
            {
                return(cursor.Select(doc => doc.GetValue(InternalField.ID)).ToList());
            }
            return(new List <BsonValue>());
        }
示例#8
0
        private List <BsonValue> CollectSelfLinks(IMongoQuery query, IMongoSortBy sortBy)
        {
            MongoCursor <BsonDocument> cursor = _collection.Find(query);

            if (sortBy != null)
            {
                cursor.SetSortOrder(sortBy);
            }
            cursor = cursor.SetFields(InternalField.SELFLINK);

            return(cursor.Select(doc => doc.GetValue(InternalField.SELFLINK)).ToList());
        }
示例#9
0
 // public methods
 /// <summary>
 /// Gets an enumerator for the result objects.
 /// </summary>
 /// <returns>An enumerator for the result objects.</returns>
 public IEnumerator <TResult> GetEnumerator()
 {
     return(_cursor.Select(_projection).GetEnumerator());
 }
示例#10
0
        public DataResult <Task <DomainUserForAdmin> > GetAsyncSequence(DataQueryOptions filter)
        {
            var query = new List <IMongoQuery>(filter.Filters.Count);

            // filtering
            List <DataFilterRule> filters = filter.Filters.Where(f => f.Value != null).ToList();

            foreach (DataFilterRule dataFilterRule in filters)
            {
                DataFilterRule f = dataFilterRule;

                if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.UserName),
                                   StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by user name
                    query.Add(Query.Text(f.Value.ToString().ToLowerInvariant()));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.Email),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by email
                    string email      = f.Value.ToString().ToLowerInvariant();
                    var    expression = new BsonRegularExpression(string.Format("^{0}.*", Regex.Escape(email)));
                    query.Add(Query <UserEntity> .Matches(p => p.Email, expression));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.ProductType),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by product type
                    var productId = Int32.Parse(f.Value.ToString());
                    query.Add(Query <UserEntity> .EQ(p => p.ProductId, productId));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.Created),
                                        StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // by created date
                    var date = (DateTime)f.Value;
                    switch (f.Type)
                    {
                    case DataFilterTypes.Equal:
                        query.Add(Query <UserEntity> .EQ(p => p.Created, date));
                        break;

                    case DataFilterTypes.LessThan:
                        query.Add(Query <UserEntity> .LT(p => p.Created, date));
                        break;

                    case DataFilterTypes.LessThanOrEqual:
                        query.Add(Query <UserEntity> .LTE(p => p.Created, date));
                        break;

                    case DataFilterTypes.GreaterThan:
                        query.Add(Query <UserEntity> .GT(p => p.Created, date));
                        break;

                    case DataFilterTypes.GreaterThanOrEqual:
                        query.Add(Query <UserEntity> .GTE(p => p.Created, date));
                        break;
                    }
                }
                else
                {
                    throw new NotSupportedException(string.Format("Filter {0} by property {1} is not supported", f.Type, f.Name));
                }
            }

            // Filter only users
            query.Add(Query <UserEntity> .EQ(p => p.Roles, DomainRoles.User));

            MongoCursor <UserEntity> cursor    = _userRepository.Collection.Find(query.Count > 0 ? Query.And(query) : Query.Null);
            IMongoSortBy             sortOrder = null;

            // sorting
            if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.UserName),
                               StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by name
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <UserEntity> .Ascending(p => p.Name)
                    : SortBy <UserEntity> .Descending(p => p.Name);
            }
            else if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.Created),
                                    StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by created
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <UserEntity> .Ascending(p => p.Created)
                    : SortBy <UserEntity> .Descending(p => p.Created);
            }
            else if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainUserForAdmin>(x => x.ProductType),
                                    StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by product type
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <UserEntity> .Ascending(p => p.ProductId)
                    : SortBy <UserEntity> .Descending(p => p.ProductId);
            }

            if (sortOrder != null)
            {
                cursor.SetSortOrder(sortOrder);
            }

            // paging

            if (filter.Skip.HasValue)
            {
                cursor.SetSkip(filter.Skip.Value);
            }

            if (filter.Take.HasValue)
            {
                cursor.SetLimit(filter.Take.Value);
            }

            // Count of results
            long?count = null;

            if (filter.Count)
            {
                count = cursor.Count();
            }

            // post-processing

            return(new DataResult <Task <DomainUserForAdmin> >(cursor.Select(GetUserDataAsync), count));
        }
示例#11
0
        public override void Update()
        {
            MongoCollection <BsonDocument> userProfileCollection = Database.GetCollection("UserProfile");
            MongoCursor <BsonDocument>     userProfiles          = userProfileCollection.FindAll();

            MongoCollection <BsonDocument> authenticationCollection       = Database.GetCollection("Authentication");
            MongoCollection <BsonDocument> membershipCollection           = Database.GetCollection("UserMembership");
            MongoCollection <BsonDocument> roleCollection                 = Database.GetCollection("UserRole");
            MongoCollection <BsonDocument> userCollection                 = Database.GetCollection("User");
            MongoCollection <BsonDocument> passwordRecoveryCollection     = Database.GetCollection("PasswordRecovery");
            MongoCollection <BsonDocument> processedScreenshotCollection  = Database.GetCollection("ProcessedScreenshot");
            MongoCollection <BsonDocument> processedVideoCollection       = Database.GetCollection("ProcessedVideo");
            MongoCollection <BsonDocument> projectCollection              = Database.GetCollection("Project");
            MongoCollection <BsonDocument> pushNotificationCollection     = Database.GetCollection("PushNotification");
            MongoCollection <BsonDocument> sendEmailCollection            = Database.GetCollection("SendEmail");
            MongoCollection <BsonDocument> statProjectDeletionCollection  = Database.GetCollection("StatProjectDeletionV2");
            MongoCollection <BsonDocument> statProjectUploadingCollection = Database.GetCollection("StatProjectUploadingV2");
            MongoCollection <BsonDocument> statUserLoginCollection        = Database.GetCollection("StatUserLoginV2");
            MongoCollection <BsonDocument> statUserRegistrationCollection = Database.GetCollection("StatUserRegistrationV2");
            MongoCollection <BsonDocument> statWatchingCollection         = Database.GetCollection("StatWatchingV2");
            MongoCollection <BsonDocument> storageFileCollection          = Database.GetCollection("StorageFile");
            MongoCollection <BsonDocument> storageSpaceCollection         = Database.GetCollection("StorageSpace");

            // Create team indexes
            Console.WriteLine("Creating temp indices...");

            roleCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            statWatchingCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            statProjectUploadingCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            statUserLoginCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            statProjectDeletionCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            statUserRegistrationCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            processedVideoCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            processedScreenshotCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));
            storageFileCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserId"), new IndexOptionsBuilder().SetSparse(true));

            // Create unique index by e-mail
            userCollection.CreateIndex(new IndexKeysBuilder().Ascending("Email"), new IndexOptionsBuilder().SetSparse(true).SetUnique(true));

            Console.WriteLine("Aggregating user data ...");

            Parallel.ForEach(userProfiles, profile =>
            {
                // Skip registrations via private domain name
                if (profile["AppName"].AsString.EndsWith(".cloudapp.net"))
                {
                    return;
                }

                // Copy from UserProfile
                string id = profile["UserId"].AsString;
                var user  = new BsonDocument
                {
                    { "_id", id },
                    { "AppName", profile["AppName"] },
                    { "Created", profile.GetValue("Created", DateTime.UtcNow) },
                    { "Modified", profile.GetValue("Modified", DateTime.UtcNow) },
                    { "Blocked", profile.GetValue("Blocked", DateTime.UtcNow) },
                    { "UserName", profile.GetValue("UserName", BsonNull.Value) },
                    { "UserNameSort", profile.GetValue("UserNameSort", BsonNull.Value) },
                    { "MaximumStorageSpace", profile.GetValue("MaximumStorageSpace", BsonValue.Create(1024 * 1024 * 1024)) },
                    { "Country", profile.GetValue("Country", BsonNull.Value) },
                    { "City", profile.GetValue("City", BsonNull.Value) },
                    { "Timezone", profile.GetValue("Timezone", "UTC") },
                    { "IsBlocked", profile.GetValue("IsBlocked", false) },
                    { "ProductId", profile.GetValue("ProductId", 0) },
                };

                // Add Memberships
                string email        = null;
                string password     = null;
                string passwordSalt = null;
                var userMemberships = new List <BsonDocument>();

                MongoCursor <BsonDocument> memberships = membershipCollection.Find(Query.EQ("UserId", id));

                foreach (BsonDocument membership in memberships)
                {
                    if (membership["IdentityProvider"].AsString == "Email")
                    {
                        email        = email ?? GetString(membership.GetValue("UserIdentifier", BsonNull.Value));
                        password     = password ?? GetString(membership.GetValue("Password", BsonNull.Value));
                        passwordSalt = passwordSalt ?? GetString(membership.GetValue("PasswordSalt", BsonNull.Value));
                    }
                    else
                    {
                        userMemberships.Add(new BsonDocument
                        {
                            { "IdentityProvider", membership["IdentityProvider"] },
                            { "UserIdentifier", membership["UserIdentifier"] },
                        });
                    }
                }

                // Override e-mail if it was found
                BsonDocument authentication = authenticationCollection.Find(Query.EQ("UserId", id)).FirstOrDefault();
                if (authentication != null)
                {
                    email = GetString(authentication.GetValue("UserEmail", BsonNull.Value)) ?? email;
                }

                user["Memberships"] = new BsonArray(userMemberships);

                if (!string.IsNullOrEmpty(email))
                {
                    user["Email"] = BsonValue.Create(email);
                }

                if (!string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(passwordSalt))
                {
                    user["Password"]     = BsonValue.Create(password);
                    user["PasswordSalt"] = BsonValue.Create(passwordSalt);
                }

                // Add Roles
                MongoCursor <BsonDocument> roles = roleCollection.Find(Query.EQ("UserId", id));
                var userRoles = new HashSet <string>(roles.Select(role => role["RoleName"].AsString))
                {
                    "User"
                };

                user["Roles"] = new BsonArray(userRoles);

                // Try to find other user by e-mail
                if (string.IsNullOrEmpty(email))
                {
                    try
                    {
                        userCollection.Insert(user);
                    }
                    catch (MongoDuplicateKeyException)
                    {
                        // Concurrent insert with retry
                    }

                    return;
                }

                BsonDocument existingUser = userCollection.FindOne(Query.EQ("Email", email));
                if (existingUser == null)
                {
                    try
                    {
                        userCollection.Insert(user);
                    }
                    catch (MongoDuplicateKeyException)
                    {
                    }

                    return;
                }

                // Merge user accounts
                var existingId = existingUser["_id"].AsString;

                // User name
                if (string.IsNullOrEmpty(GetString(existingUser.GetValue("UserName", BsonNull.Value))))
                {
                    existingUser["UserName"]     = user["UserName"];
                    existingUser["UserNameSort"] = user["UserNameSort"];
                }

                // Country
                if (string.IsNullOrEmpty(GetString(existingUser.GetValue("Country", BsonNull.Value))))
                {
                    existingUser["Country"] = user["Country"];
                }

                // City
                if (string.IsNullOrEmpty(GetString(existingUser.GetValue("City", BsonNull.Value))))
                {
                    existingUser["City"] = user["City"];
                }

                // Memberships
                existingUser["Memberships"] = existingUser["Memberships"].AsBsonArray.AddRange(userMemberships);

                // Roles
                foreach (BsonValue role in existingUser["Roles"].AsBsonArray)
                {
                    userRoles.Add(role.AsString);
                }

                user["Roles"] = new BsonArray(userRoles);

                // Passwords
                if (!string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(passwordSalt) &&
                    (string.IsNullOrEmpty(GetString(existingUser.GetValue("Password", BsonNull.Value))) ||
                     string.IsNullOrEmpty(GetString(existingUser.GetValue("PasswordSalt", BsonNull.Value)))))
                {
                    existingUser["Password"]     = BsonValue.Create(password);
                    existingUser["PasswordSalt"] = BsonValue.Create(passwordSalt);
                }

                // Change data ownership
                passwordRecoveryCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                processedScreenshotCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                processedVideoCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                projectCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                pushNotificationCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                sendEmailCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                statProjectDeletionCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                statProjectUploadingCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                statUserLoginCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                statUserRegistrationCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                statWatchingCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                storageFileCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);
                storageSpaceCollection.Update(Query.EQ("UserId", id), MongoDB.Driver.Builders.Update.Set("UserId", existingId), UpdateFlags.Multi);

                // Save user changes
                userCollection.Save(existingUser);
            });

            // Remove temp indexes
            Console.WriteLine("Dropping temp indices...");

            statWatchingCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            statProjectUploadingCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            statUserLoginCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            statProjectDeletionCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            statUserRegistrationCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            processedVideoCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            processedScreenshotCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));
            storageFileCollection.DropIndex(new IndexKeysBuilder().Ascending("UserId"));

            // Create indices
            userCollection.CreateIndex(new IndexKeysBuilder().Ascending("Created"), new IndexOptionsBuilder().SetSparse(true));
            userCollection.CreateIndex(new IndexKeysBuilder().Ascending("UserNameSort"), new IndexOptionsBuilder().SetSparse(true));
            userCollection.CreateIndex(new IndexKeysBuilder().Ascending("Roles"), new IndexOptionsBuilder().SetSparse(true));
            userCollection.CreateIndex(
                new IndexKeysBuilder().Ascending("Memberships.IdentityProvider", "Memberships.UserIdentifier"),
                new IndexOptionsBuilder().SetSparse(true).SetUnique(true));
        }
        public async Task <DataResult <Task <DomainProjectForAdmin> > > GetAsyncSequenceAsync(DataQueryOptions filter)
        {
            var query = new List <IMongoQuery>(filter.Filters.Count);

            // filtering
            List <DataFilterRule> filters = filter.Filters.Where(f => f.Value != null).ToList();

            foreach (DataFilterRule dataFilterRule in filters)
            {
                DataFilterRule f = dataFilterRule;

                if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.Name),
                                   StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by name
                    query.Add(Query.Text(f.Value.ToString().ToLowerInvariant()));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.ProductType),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by product type
                    var productId = Int32.Parse(f.Value.ToString());
                    query.Add(Query <ProjectEntity> .EQ(p => p.ProductId, productId));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.UserId),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by user id
                    query.Add(Query <ProjectEntity> .EQ(p => p.UserId, f.Value.ToString()));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.UserName),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by user name
                    List <UserEntity> profiles = await _userRepository.FindByNameAsync(f.Value.ToString());

                    if (profiles.Count == 0)
                    {
                        // no users found
                        return(new DataResult <Task <DomainProjectForAdmin> >(new Task <DomainProjectForAdmin>[] { }));
                    }

                    List <string> allIds = profiles.Select(prof => prof.Id).ToList();
                    query.Add(Query <ProjectEntity> .Where(p => allIds.Contains(p.UserId)));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.Created),
                                        StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // by created date
                    var date = (DateTime)f.Value;
                    switch (f.Type)
                    {
                    case DataFilterTypes.Equal:
                        query.Add(Query <ProjectEntity> .EQ(p => p.Created, date));
                        break;

                    case DataFilterTypes.LessThan:
                        query.Add(Query <ProjectEntity> .LT(p => p.Created, date));
                        break;

                    case DataFilterTypes.LessThanOrEqual:
                        query.Add(Query <ProjectEntity> .LTE(p => p.Created, date));
                        break;

                    case DataFilterTypes.GreaterThan:
                        query.Add(Query <ProjectEntity> .GT(p => p.Created, date));
                        break;

                    case DataFilterTypes.GreaterThanOrEqual:
                        query.Add(Query <ProjectEntity> .GTE(p => p.Created, date));
                        break;
                    }
                }
                else
                {
                    throw new NotSupportedException(string.Format("Filter {0} by property {1} is not supported", f.Type, f.Name));
                }
            }

            if (!filters.Any() && !string.IsNullOrEmpty(filter.OrderBy))
            {
                // MongoDb 2.6 HACK!!!
                // adding fake query to hint proper index

                if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.Name),
                                   StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // order by name
                    query.Add(Query <ProjectEntity> .Exists(p => p.Name));
                }
                else if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.Created),
                                        StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // order by created
                    query.Add(Query <ProjectEntity> .Exists(p => p.Created));
                }
                else if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.ProductType),
                                        StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // order by product type
                    query.Add(Query <ProjectEntity> .Exists(p => p.ProductId));
                }
            }

            MongoCursor <ProjectEntity> cursor = _projectRepository.Collection.Find(query.Count > 0 ? Query.And(query) : Query.Null);
            IMongoSortBy sortOrder             = null;

            // sorting
            if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.Name),
                               StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by name
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <ProjectEntity> .Ascending(p => p.Name)
                    : SortBy <ProjectEntity> .Descending(p => p.Name);
            }
            else if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.Created),
                                    StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by created
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <ProjectEntity> .Ascending(p => p.Created)
                    : SortBy <ProjectEntity> .Descending(p => p.Created);
            }
            else if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <DomainProjectForAdmin>(x => x.ProductType),
                                    StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by product type
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <ProjectEntity> .Ascending(p => p.ProductId)
                    : SortBy <ProjectEntity> .Descending(p => p.ProductId);
            }

            if (sortOrder != null)
            {
                cursor.SetSortOrder(sortOrder);
            }

            // paging

            if (filter.Skip.HasValue)
            {
                cursor.SetSkip(filter.Skip.Value);
            }

            if (filter.Take.HasValue)
            {
                cursor.SetLimit(filter.Take.Value);
            }

            // Count of results
            long?count = null;

            if (filter.Count)
            {
                count = cursor.Count();
            }

            // post-processing

            return(new DataResult <Task <DomainProjectForAdmin> >(cursor.Select(GetProjectDataAsync), count));
        }