Beispiel #1
0
        public void TestCursors()
        {
            this.DbClient = new MongoClient(connectionString);
            this.DbServer = this.DbClient.GetServer();
            this.Database = this.DbServer.GetDatabase("test_client");
            Collection2   = Database.GetCollection <DBObject>("cursors_sample");

            MongoCursor <DBObject> cursor = Collection2.FindAll();

            //Console.WriteLine("cursor count = {0}", cursor.Count());

            cursor.SetSkip(0);

            var lst = cursor.Take(10).ToList();

            foreach (var l in lst)
            {
                Console.Write(l.data + ", ");
            }
            Console.WriteLine();

            cursor = Collection2.FindAll();
            cursor.SetSkip(10);
            lst = cursor.Take(10).ToList();
            foreach (var l in lst)
            {
                Console.Write(l.data + ", ");
            }
            Console.WriteLine();

            cursor = Collection2.FindAll();
            cursor.SetSkip(0);
            lst = cursor.Take(10).ToList();
            foreach (var l in lst)
            {
                Console.Write(l.data + ", ");
            }
            Console.WriteLine();

            Console.WriteLine("cursor count = {0}", cursor.Count());

            cursor = Collection2.FindAll();
            Filter filter   = new Filter();
            var    filtered = cursor.Where(obj => filter.Check(obj.data)).Skip(10).Take(10).ToList();

            Console.WriteLine("filtered count: " + filtered.Count);
            foreach (var o in filtered)
            {
                Console.Write(o.data + ", ");
            }
            Console.WriteLine();
        }
Beispiel #2
0
        public IEnumerable <Item> LimitItems(string ownerId, int start, int limit)
        {
            MongoCursor <Item> mongoCursor = (MongoCursor <Item>)AllItems(ownerId);

            mongoCursor = mongoCursor.SetSkip(start).SetLimit(limit);
            return(mongoCursor);
        }
Beispiel #3
0
 private void ApplySkip(MongoCursor <BsonDocument> cursor, int?skipCount)
 {
     if (skipCount.HasValue)
     {
         cursor.SetSkip(skipCount.Value);
     }
 }
Beispiel #4
0
        /// <summary>
        /// 获取数据列表
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="DbName">数据库名称</param>
        /// <param name="TableName">表名</param>
        /// <param name="where">查询条件</param>
        /// <param name="orderby">排序</param>
        /// <param name="fields">返回字段</param>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="count">记录总数</param>
        /// <returns>数据列表</returns>
        public static List <T> GetPaged <T>(string DbName, string TableName, BsonDocument where, string[] orderby, BsonDocument fields, int pageIndex, int pageSize)
        {
            List <T> list = new List <T>();

            try
            {
                MongoDatabase db = mongo.GetDatabase(DbName);//数据库名字
                if (db == null)
                {
                    throw new ArgumentNullException("db not found.");
                }
                MongoCollection <BsonDocument> categories = db.GetCollection <BsonDocument>(TableName);//表的名字
                MongoCursor <T> cursor = categories.FindAs <T>(new QueryComplete(where));
                cursor.SetSkip(((pageIndex - 1) * pageSize));
                cursor.SetLimit(pageSize);
                cursor.SetSortOrder(SortBy.Descending(orderby));
                foreach (T t in cursor)
                {
                    list.Add(t);
                }
            }
            catch (Exception ex)
            {
                LogService.Write(ex);
            }
            return(list);
        }
Beispiel #5
0
        /// <summary>
        /// 返回mongo查询数据
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="query">查询条件</param>
        /// <param name="collectionName">表名</param>
        /// <param name="filter">过滤条件</param>
        /// <returns>mongo数据</returns>
        public MongoCursor <T> QueryCursor <T>(IMongoQuery query, string collectionName, BaseFilter filter)
        {
            MongoCollection collection = GetMongoCollection(collectionName);

            filter.RecordCount = Convert.ToInt32(collection.Count(query));
            SortByDocument  sortByDocument = GetSortFromStr(filter.OrderbyStr);
            MongoCursor <T> mongoCursor    = collection.FindAs <T>(query);

            //查询性能分析
            //BsonDocument document = collection.FindAs<T>(query).Explain();
            if (sortByDocument != null)
            {
                mongoCursor = mongoCursor.SetSortOrder(sortByDocument);
            }

            if (filter.PageSize == 0)
            {
                filter.PageSize = DefaultPageSize;
            }
            if (filter.PageNo == 0)
            {
                filter.PageNo = DefaultPageNo;
            }
            return(mongoCursor.SetSkip(filter.PageSize * (filter.PageNo - 1)).SetLimit(filter.PageSize));
        }
Beispiel #6
0
        public List <T> Page <T>(int skip, int limit, string orderBy) where T : class, new()
        {
            MongoCursor <T> cursor = mongoDb.GetCollection <T>(GetTypeName(typeof(T))).FindAll();

            cursor.SetSkip(skip).SetLimit(limit);

            if (!String.IsNullOrEmpty(orderBy))
            {
                cursor.SetSortOrder(SortBy.Descending(orderBy));
            }
            return(cursor.ToList());
        }
Beispiel #7
0
        public List <T> Page <T>(System.Linq.Expressions.Expression <Func <T, bool> > expression, int skip, int limit, string orderBy) where T : class, new()
        {
            IMongoQuery query = Query <T> .Where(expression);

            MongoCursor <T> cursor = mongoDb.GetCollection <T>(GetTypeName(typeof(T))).Find(query);

            cursor.SetSkip(skip).SetLimit(limit);

            if (!String.IsNullOrEmpty(orderBy))
            {
                cursor.SetSortOrder(SortBy.Descending(orderBy));
            }

            return(cursor.ToList());
        }
Beispiel #8
0
        public static MongoCursor ApplySkipTake(MongoCursor mongoCursor, ISortableRequest dataRequest)
        {
            int take = MongoSortingUtils.GetTake(dataRequest);

            if (take > 0)
            {
                mongoCursor = mongoCursor.SetLimit(take);
            }
            int skip = MongoSortingUtils.GetSkip(dataRequest);

            if (skip > 0)
            {
                mongoCursor = mongoCursor.SetSkip(skip);
            }
            return(mongoCursor);
        }
Beispiel #9
0
        /// <summary>
        /// Perform a full text query on all fields indexed as text.
        /// </summary>
        /// <returns>First 50 results</returns>
        public List <T> TextSearch <T>(string searchStr, int skip, int limit, string orderBy) where T : class, new()
        {
            MongoCursor <T> cursor = mongoDb.GetCollection <T>(GetTypeName(typeof(T))).Find(Query.Text(searchStr));

            if (skip > 0)
            {
                cursor.SetSkip(skip);
            }

            cursor.SetLimit(limit);

            if (orderBy != null)
            {
                cursor.SetSortOrder(SortBy.Descending(orderBy));
            }

            return(cursor.ToList());
        }
Beispiel #10
0
        private MongoCursor <BsonDocument> Find(string collectionName, string query, string fields, string sort, int skip, int limit)
        {
            MongoCollection <BsonDocument> collection = Database.GetCollection <BsonDocument>(collectionName);
            MongoCursor <BsonDocument>     cursor     = (string.IsNullOrEmpty(query)) ? collection.FindAll() : collection.Find(new QueryDocument(ParseQuery(query)));

            if (!string.IsNullOrEmpty(fields))
            {
                ParseQuery(fields).ToList().ForEach(item =>
                {
                    if (item.Value == 0)
                    {
                        cursor.SetFields(Fields.Exclude(item.Name));
                    }
                    else
                    {
                        cursor.SetFields(Fields.Include(item.Name));
                    }
                });
            }

            if (!string.IsNullOrEmpty(sort))
            {
                ParseQuery(sort).ToList().ForEach(itemtoSort =>
                {
                    if (itemtoSort.Value > 0)
                    {
                        cursor.SetSortOrder(SortBy.Ascending(itemtoSort.Name));
                    }
                    else
                    {
                        cursor.SetSortOrder(SortBy.Descending(itemtoSort.Name));
                    }
                });
            }

            cursor.SetSkip(skip);
            cursor.SetLimit(limit);
            return(cursor);
        }
Beispiel #11
0
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="filterList"></param>
        /// <param name="sortByMap"> var sort = new SortByDocument { { "_id", -1 } }; ->这里1为ASC, -1为DESC</param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List <T> PageList(List <Expression <Func <T, bool> > > filterList, Dictionary <string, sbyte> sortByMap = null, int?pageIndex = null, int?pageSize = null, string[] fields = null)
        {
            MongoCursor <T> cursor = null;

            if (null != filterList && filterList.Count > 0)
            {
                var findQueryList = (from expression in filterList where null != expression select Query <T> .Where(expression)).ToList();

                var findQuery = Query.And(findQueryList);
                cursor = this._mongoCollection.FindAs <T>(findQuery);
            }
            else
            {
                cursor = this._mongoCollection.FindAllAs <T>();
            }

            if (null != sortByMap)
            {
                var orderByQuery = new SortByDocument(sortByMap);
                cursor = cursor.SetSortOrder(orderByQuery);
            }
            if (fields != null && fields.Any())
            {
                cursor = cursor.SetFields(fields);
            }
            if (pageIndex.HasValue)
            {
                if (!pageSize.HasValue)
                {
                    pageSize = 30;
                }

                List <T> list = cursor.SetSkip((pageIndex.Value - 1) * pageSize.Value).SetLimit(pageSize.Value).ToList();
                return(list);
            }
            return(cursor.ToList());
        }
Beispiel #12
0
        public List <T> Page <T>(DbQueryParams qParams) where T : class, new()
        {
            // First query part consists of search params with specified operator between
            List <IMongoQuery> queries = new List <IMongoQuery>();

            foreach (var item in qParams.QueryParams)
            {
                queries.Add(Query.Matches(item.Key, new BsonRegularExpression(String.Format("(?:{0})", item.Value), "is")));
            }

            var query = qParams.Operator == QueryOperator.AND ? Query.And(queries) : Query.Or(queries);

            MongoCursor <T> cursor = mongoDb.GetCollection <T>(GetTypeName(typeof(T))).Find(query);

            cursor.SetSkip(qParams.SkipRecords).SetLimit(qParams.Count);

            // Setting the Sort params
            if (qParams.SortParams != null && qParams.SortParams.Count > 0)
            {
                SortByBuilder sbb = new SortByBuilder();
                foreach (KeyValuePair <string, bool> sortItem in qParams.SortParams)
                {
                    if (sortItem.Value)
                    {
                        sbb.Ascending(sortItem.Key);
                    }
                    else
                    {
                        sbb.Descending(sortItem.Key);
                    }
                }
                cursor.SetSortOrder(sbb);
            }

            return(cursor.ToList());
        }
 private void ApplySkip(MongoCursor<BsonDocument> cursor, int? skipCount)
 {
     if (skipCount.HasValue)
         cursor.SetSkip(skipCount.Value);
 }
    public List <BsonDocument> ExecuteQueryBsonDoc(string table,                 // 表名
                                                   IMongoQuery query,            // 查询条件,外部要自拼接
                                                   string[] fields  = null,
                                                   string sort      = "",
                                                   bool asc         = true,
                                                   int skip         = 0,
                                                   int limt         = 0,
                                                   string[] indexes = null)
    {
        // 表不存在,直接返回
        if (!TableExists(table))
        {
            return(null);
        }

        List <BsonDocument> retlist = new List <BsonDocument>();

        try
        {
            var cb = check_table(table);
            MongoCursor <BsonDocument> ret = null;
            if (query == null)
            {
                ret = cb.FindAll();
            }
            else
            {
                ret = cb.Find(query);
            }

            if (fields != null)
            {
                ret = ret.SetFields(fields);
            }

            if (sort != string.Empty)
            {
                if (asc)
                {
                    ret = ret.SetSortOrder(SortBy.Ascending(sort));
                }
                else
                {
                    ret = ret.SetSortOrder(SortBy.Descending(sort));
                }
            }

            if (skip > 0)
            {
                ret = ret.SetSkip(skip);
            }
            if (limt > 0)
            {
                ret = ret.SetLimit(limt);
            }

            var it = ret.GetEnumerator();

            while (it.MoveNext())
            {
                retlist.Add(it.Current);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            retlist.Clear();
        }
        return(retlist);
    }
        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));
        }
        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));
        }
 public IMongoCursor SetSkip(int skip)
 {
     return(new MongoCursorProxy(_mongoMongoCursor.SetSkip(skip)));
 }
        public async Task <DataResult <Watch> > GetSequenceAsync(DataQueryOptions filter, string userId)
        {
            var query = new List <IMongoQuery>(filter.Filters.Count);

            // Filtering
            List <DataFilterRule> filters = filter.Filters.Where(f => f.Value != null).ToList();
            string requestedUserId        = null;
            var    searchList             = new List <string>();

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

                if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.Name),
                                   StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by name
                    searchList.Add(f.Value.ToString().ToLowerInvariant());
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.UserId),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by user id
                    requestedUserId = f.Value.ToString();
                    query.Add(Query <ProjectEntity> .EQ(p => p.UserId, requestedUserId));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.Generator),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by product id
                    int productId = Int32.Parse(f.Value.ToString());
                    query.Add(Query <ProjectEntity> .EQ(p => p.ProductId, productId));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.ProjectType),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by project type
                    object projectType = Enum.Parse(typeof(ProjectType), f.Value.ToString());
                    query.Add(Query <ProjectEntity> .EQ(p => p.ProjectType, (int)projectType));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.ProjectSubtype),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by project subtype
                    object projectSubtype = Enum.Parse(typeof(ProjectSubtype), f.Value.ToString());
                    query.Add(Query <ProjectEntity> .EQ(p => p.ProjectSubtype, (int)projectSubtype));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.External.VideoUri),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by external video uri
                    query.Add(Query <ProjectEntity> .EQ(p => p.VideoSource, f.Value));
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(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 if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.HitsCount),
                                        StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // by hits count
                    int threshold = Int32.Parse(f.Value.ToString());

                    if (f.Type == DataFilterTypes.GreaterThan)
                    {
                        query.Add(Query <ProjectEntity> .GT(p => p.HitsCount, threshold));
                    }
                    else if (f.Type == DataFilterTypes.GreaterThanOrEqual)
                    {
                        query.Add(Query <ProjectEntity> .GTE(p => p.HitsCount, threshold));
                    }
                    else
                    {
                        query.Add(Query <ProjectEntity> .EQ(p => p.HitsCount, threshold));
                    }
                }
                else if (string.Compare(f.Name, NameOfHelper.PropertyName <Watch>(x => x.State),
                                        StringComparison.OrdinalIgnoreCase) == 0 && f.Type == DataFilterTypes.Equal)
                {
                    // by video state
                    var videoState = (WatchState)Enum.Parse(typeof(WatchState), f.Value.ToString());
                    if (videoState == WatchState.Uploading)
                    {
                        var avsx = Query <ProjectEntity> .EQ(p => p.AvsxFileId, null);

                        var originalFileId = Query <ProjectEntity> .EQ(p => p.OriginalVideoFileId, null);

                        var externalSource = Query <ProjectEntity> .EQ(p => p.VideoSource, null);

                        query.Add(Query.Or(avsx, Query.And(originalFileId, externalSource)));
                    }
                    else if (videoState == WatchState.Encoding)
                    {
                        var avsx = Query <ProjectEntity> .NE(p => p.AvsxFileId, null);

                        var originalFileId = Query <ProjectEntity> .NE(p => p.OriginalVideoFileId, null);

                        var encodedVideosName = NameOfHelper.PropertyName <ProjectEntity>(x => x.EncodedVideos);
                        var encodedVideos     = Query.NotExists(string.Format("{0}.0", encodedVideosName));

                        query.Add(Query.And(avsx, originalFileId, encodedVideos));
                    }
                    else if (videoState == WatchState.Ready)
                    {
                        var avsx = Query <ProjectEntity> .NE(p => p.AvsxFileId, null);

                        var externalSource = Query <ProjectEntity> .NE(p => p.VideoSource, null);

                        var originalFileId = Query <ProjectEntity> .NE(p => p.OriginalVideoFileId, null);

                        var encodedVideosName = NameOfHelper.PropertyName <ProjectEntity>(x => x.EncodedVideos);
                        var encodedVideos     = Query.Exists(string.Format("{0}.0", encodedVideosName));

                        query.Add(Query.And(avsx, Query.Or(externalSource, Query.And(originalFileId, encodedVideos))));
                    }
                }
                else
                {
                    throw new NotSupportedException(string.Format("Filter {0} by property {1} is not supported", f.Type, f.Name));
                }
            }

            string searchText = String.Join(" ", searchList);

            if (!String.IsNullOrEmpty(searchText))
            {
                query.Add(Query.Text(searchText));
            }

            // we should see only public videos for other users
            if (requestedUserId != userId)
            {
                query.Add(Query <ProjectEntity> .EQ(p => p.Access, (int)ProjectAccess.Public));
            }

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

            // Sorting
            IMongoSortBy sortOrder = null;

            if (string.Compare(filter.OrderBy, NameOfHelper.PropertyName <Watch>(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 <Watch>(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 <Watch>(x => x.HitsCount),
                                    StringComparison.OrdinalIgnoreCase) == 0)
            {
                // order by hits count
                sortOrder = filter.OrderByDirection == OrderByDirections.Asc
                    ? SortBy <ProjectEntity> .Ascending(p => p.HitsCount)
                    : SortBy <ProjectEntity> .Descending(p => p.HitsCount);
            }

            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();
            }

            List <ProjectEntity> projects = cursor.ToList();

            // Get comments and total comment counts
            string[] projectIds = projects.Select(p => p.Id).ToArray();
            Dictionary <string, int> commentsCounts = (await _commentRepository.GetCommentsCountByProjectsAsync(projectIds)).ToDictionary(c => c.ProjectId, c => c.CommentsCount);
            Dictionary <string, List <CommentEntity> > recentComments = await _commentRepository.GetRecentCommentsByProjectsAsync(projectIds, RecentCommentsLimit);

            // Get project user ids united with comment user ids to load entities in batch
            string[] userIds = GetUserIds(projects, recentComments);
            Dictionary <string, UserEntity> users = (await _userRepository.GetUsersByIdsAsync(userIds)).ToDictionary(u => u.Id);

            // Post-processing
            return(new DataResult <Watch>(projects.Select(p => AggregateProject(p, userId, users, commentsCounts, recentComments)), count));
        }