Esempio n. 1
0
        public static FilterDefinition <MongoAssetEntity> BuildFilter(this ClrQuery query, DomainId appId, DomainId?parentId)
        {
            var filters = new List <FilterDefinition <MongoAssetEntity> >
            {
                Filter.Eq(x => x.IndexedAppId, appId),
                Filter.Eq(x => x.IsDeleted, false)
            };

            if (parentId.HasValue)
            {
                if (parentId == DomainId.Empty)
                {
                    filters.Add(
                        Filter.Or(
                            Filter.Exists(x => x.ParentId, false),
                            Filter.Eq(x => x.ParentId, DomainId.Empty)));
                }
                else
                {
                    filters.Add(Filter.Eq(x => x.ParentId, parentId.Value));
                }
            }

            var(filter, last) = query.BuildFilter <MongoAssetEntity>(false);

            if (filter != null)
            {
                if (last)
                {
                    filters.Add(filter);
                }
                else
                {
                    filters.Insert(0, filter);
                }
            }

            return(Filter.And(filters));
        }
Esempio n. 2
0
        public void Should_add_fields_from_sorting()
        {
            var query = new ClrQuery
            {
                Sort = new List <SortNode>
                {
                    new SortNode("field1", SortOrder.Ascending),
                    new SortNode("field1", SortOrder.Ascending),
                    new SortNode("field2", SortOrder.Ascending)
                }
            };

            var fields = query.GetAllFields();

            var expected = new HashSet <string>
            {
                "field1",
                "field2"
            };

            Assert.Equal(expected, fields);
        }
Esempio n. 3
0
        public virtual ClrQuery ParseQuery(Context context, ISchemaEntity schema, Q q)
        {
            Guard.NotNull(context);
            Guard.NotNull(schema);

            using (Profiler.TraceMethod <ContentQueryParser>())
            {
                var result = new ClrQuery();

                if (!string.IsNullOrWhiteSpace(q?.JsonQuery))
                {
                    result = ParseJson(context, schema, q.JsonQuery);
                }
                else if (!string.IsNullOrWhiteSpace(q?.ODataQuery))
                {
                    result = ParseOData(context, schema, q.ODataQuery);
                }

                if (result.Sort.Count == 0)
                {
                    // changed default sorting by order no instead of lastModified so that ordering mechanism would work.
                    result.Sort.Add(new SortNode(new List <string> {
                        "orderNo"
                    }, SortOrder.Descending));
                }

                if (result.Take == long.MaxValue)
                {
                    result.Take = options.DefaultPageSize;
                }
                else if (result.Take > options.MaxResults)
                {
                    result.Take = options.MaxResults;
                }

                return(result);
            }
        }
Esempio n. 4
0
        public void Should_add_fields_from_filters()
        {
            var query = new ClrQuery
            {
                Filter =
                    ClrFilter.And(
                        ClrFilter.Not(
                            ClrFilter.Eq("field1", 1)),
                        ClrFilter.Or(
                            ClrFilter.Eq("field2", 2),
                            ClrFilter.Eq("field2", 4)))
            };

            var fields = query.GetAllFields();

            var expected = new HashSet <string>
            {
                "field1",
                "field2"
            };

            Assert.Equal(expected, fields);
        }
Esempio n. 5
0
        public static SortDefinition <T> BuildSort <T>(this ClrQuery query)
        {
            if (query.Sort.Count > 0)
            {
                var sorts = new List <SortDefinition <T> >();

                foreach (var sort in query.Sort)
                {
                    sorts.Add(OrderBy <T>(sort));
                }

                if (sorts.Count > 1)
                {
                    return(Builders <T> .Sort.Combine(sorts));
                }
                else
                {
                    return(sorts[0]);
                }
            }

            return(null);
        }
Esempio n. 6
0
        private async Task TransformFilterAsync(ClrQuery query, Context context, ISchemaEntity?schema)
        {
            if (query.Filter != null && schema != null)
            {
                query.Filter = await GeoQueryTransformer.TransformAsync(query.Filter, context, schema, textIndex);
            }

            if (!string.IsNullOrWhiteSpace(query.FullText))
            {
                if (schema == null)
                {
                    throw new InvalidOperationException();
                }

                var textQuery = new TextQuery(query.FullText, TextFilter.ShouldHaveSchemas(schema.Id));

                var fullTextIds = await textIndex.SearchAsync(context.App, textQuery, context.Scope());

                var fullTextFilter = ClrFilter.Eq("id", "__notfound__");

                if (fullTextIds?.Any() == true)
                {
                    fullTextFilter = ClrFilter.In("id", fullTextIds.Select(x => x.ToString()).ToList());
                }

                if (query.Filter != null)
                {
                    query.Filter = ClrFilter.And(query.Filter, fullTextFilter);
                }
                else
                {
                    query.Filter = fullTextFilter;
                }

                query.FullText = null;
            }
        }
        private async Task <IResultList <IContentEntity> > QueryAsync(ClrQuery clrQuery, int take = 1000, int skip = 100, DomainId?id = null)
        {
            if (clrQuery.Take == long.MaxValue)
            {
                clrQuery.Take = take;
            }

            if (clrQuery.Skip == 0)
            {
                clrQuery.Skip = skip;
            }

            if (clrQuery.Sort.Count == 0)
            {
                clrQuery.Sort = new List <SortNode>
                {
                    new SortNode("LastModified", SortOrder.Descending)
                };
            }

            var contents = await _.ContentRepository.QueryAsync(_.RandomApp(), _.RandomSchema(), clrQuery, id, SearchScope.All);

            return(contents);
        }
Esempio n. 8
0
        public static void ParseFilter(this ODataUriParser query, ClrQuery result)
        {
            SearchClause searchClause;

            try
            {
                searchClause = query.ParseSearch();
            }
            catch (ODataException ex)
            {
                throw new ValidationException("Query $search clause not valid.", new ValidationError(ex.Message));
            }

            if (searchClause != null)
            {
                result.FullText = SearchTermVisitor.Visit(searchClause.Expression).ToString();
            }

            FilterClause filterClause;

            try
            {
                filterClause = query.ParseFilter();
            }
            catch (ODataException ex)
            {
                throw new ValidationException("Query $filter clause not valid.", new ValidationError(ex.Message));
            }

            if (filterClause != null)
            {
                var filter = FilterVisitor.Visit(filterClause.Expression);

                result.Filter = Optimizer <ClrValue> .Optimize(filter);
            }
        }
Esempio n. 9
0
 public static FilterDefinition <MongoContentEntity> ToFilter(this ClrQuery query, Guid schemaId, ICollection <Guid> ids, Status[] status)
 {
     return(CreateFilter(null, schemaId, ids, status, query));
 }
Esempio n. 10
0
        private async Task <IResultList <IContentEntity> > QueryAsync(Status[]?status, ClrQuery query)
        {
            query.Top = 1000;

            query.Skip = 100;

            query.Sort = new List <SortNode>
            {
                new SortNode("LastModified", SortOrder.Descending)
            };

            var contents = await _.ContentRepository.QueryAsync(_.RandomApp(), _.RandomSchema(), status, true, query, true);

            return(contents);
        }
Esempio n. 11
0
        public static IFindFluent <T, T> QuerySkip <T>(this IFindFluent <T, T> cursor, ClrQuery query)
        {
            if (query.Skip > 0)
            {
                cursor = cursor.Skip((int)query.Skip);
            }

            return(cursor);
        }
Esempio n. 12
0
 public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, ClrQuery query, DomainId?referenced)
 {
     using (Profiler.TraceMethod <MongoContentRepository>("QueryAsyncByQuery"))
     {
         return(await queryContentsByQuery.DoAsync(app, schema, query, referenced, SearchScope.Published));
     }
 }
Esempio n. 13
0
 public static IFindFluent <MongoAssetEntity, MongoAssetEntity> AssetSort(this IFindFluent <MongoAssetEntity, MongoAssetEntity> cursor, ClrQuery query)
 {
     return(cursor.Sort(query.BuildSort <MongoAssetEntity>()));
 }
Esempio n. 14
0
        public async Task <IResultList <IContentEntity> > DoAsync(IAppEntity app, ISchemaEntity schema, ClrQuery query, DomainId?referenced, SearchScope scope)
        {
            Guard.NotNull(app, nameof(app));
            Guard.NotNull(schema, nameof(schema));
            Guard.NotNull(query, nameof(query));

            try
            {
                query = query.AdjustToModel(schema.SchemaDef);

                List <DomainId>?fullTextIds = null;

                if (!string.IsNullOrWhiteSpace(query.FullText))
                {
                    var searchFilter = SearchFilter.ShouldHaveSchemas(schema.Id);

                    fullTextIds = await indexer.SearchAsync(query.FullText, app, searchFilter, scope);

                    if (fullTextIds?.Count == 0)
                    {
                        return(ResultList.CreateFrom <IContentEntity>(0));
                    }
                }

                var filter = CreateFilter(schema.AppId.Id, schema.Id, fullTextIds, query, referenced);

                var contentCount = Collection.Find(filter).CountDocumentsAsync();
                var contentItems = FindContentsAsync(query, filter);

                var(items, total) = await AsyncHelper.WhenAll(contentItems, contentCount);

                foreach (var entity in items)
                {
                    entity.ParseData(schema.SchemaDef, converter);
                }

                return(ResultList.Create <IContentEntity>(total, items));
            }
            catch (MongoCommandException ex) when(ex.Code == 96)
            {
                throw new DomainException(T.Get("common.resultTooLarge"));
            }
            catch (MongoQueryException ex) when(ex.Message.Contains("17406"))
            {
                throw new DomainException(T.Get("common.resultTooLarge"));
            }
        }
Esempio n. 15
0
        public async Task <IResultList <IContentEntity> > DoAsync(IAppEntity app, ISchemaEntity schema, ClrQuery query, SearchScope scope)
        {
            Guard.NotNull(app, nameof(app));
            Guard.NotNull(schema, nameof(schema));
            Guard.NotNull(query, nameof(query));

            try
            {
                query = query.AdjustToModel(schema.SchemaDef);

                List <Guid>?fullTextIds = null;

                if (!string.IsNullOrWhiteSpace(query.FullText))
                {
                    var searchFilter = SearchFilter.ShouldHaveSchemas(schema.Id);

                    fullTextIds = await indexer.SearchAsync(query.FullText, app, searchFilter, scope);

                    if (fullTextIds?.Count == 0)
                    {
                        return(ResultList.CreateFrom <IContentEntity>(0));
                    }
                }

                var filter = CreateFilter(schema.Id, fullTextIds, query);

                var contentCount = Collection.Find(filter).CountDocumentsAsync();
                var contentItems = FindContentsAsync(query, filter);

                await Task.WhenAll(contentItems, contentCount);

                foreach (var entity in contentItems.Result)
                {
                    entity.ParseData(schema.SchemaDef, converter);
                }

                return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result));
            }
            catch (MongoCommandException ex) when(ex.Code == 96)
            {
                throw new DomainException("Result set is too large to be retrieved. Use $take parameter to reduce the number of items.");
            }
            catch (MongoQueryException ex) when(ex.Message.Contains("17406"))
            {
                throw new DomainException("Result set is too large to be retrieved. Use $take parameter to reduce the number of items.");
            }
        }
Esempio n. 16
0
 private static bool IsSatisfiedByIndex(ClrQuery query)
 {
     return(query.Sort?.Any(x => x.Path == DefaultOrderField && x.Order == SortOrder.Descending) == true);
 }
        private async Task <IResultList <IAssetEntity> > QueryAsync(DomainId?parentId, ClrQuery clrQuery)
        {
            clrQuery.Top = 1000;

            clrQuery.Skip = 100;

            if (clrQuery.Sort.Count == 0)
            {
                clrQuery.Sort = new List <SortNode>
                {
                    new SortNode("LastModified", SortOrder.Descending),
                    new SortNode("Id", SortOrder.Descending)
                };
            }

            var q =
                Q.Empty
                .WithoutTotal()
                .WithQuery(clrQuery);

            var assets = await _.AssetRepository.QueryAsync(_.RandomAppId(), parentId, q);

            return(assets);
        }
 public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, Status[]?status, bool inDraft, ClrQuery query, bool includeDraft = true)
 {
     using (Profiler.TraceMethod <MongoContentRepository>("QueryAsyncByQuery"))
     {
         return(await queryContentsByQuery.DoAsync(app, schema, query, status, inDraft, includeDraft));
     }
 }
Esempio n. 19
0
 public static IFindFluent <T, T> QuerySort <T>(this IFindFluent <T, T> cursor, ClrQuery query)
 {
     return(cursor.Sort(query.BuildSort <T>()));
 }
        public async Task <IResultList <IAssetEntity> > QueryAsync(DomainId appId, DomainId?parentId, ClrQuery query)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByQuery"))
            {
                try
                {
                    query = query.AdjustToModel();

                    var filter = query.BuildFilter(appId, parentId);

                    var assetCount = Collection.Find(filter).CountDocumentsAsync();
                    var assetItems =
                        Collection.Find(filter)
                        .QueryLimit(query)
                        .QuerySkip(query)
                        .QuerySort(query)
                        .ToListAsync();

                    var(items, total) = await AsyncHelper.WhenAll(assetItems, assetCount);

                    return(ResultList.Create <IAssetEntity>(total, items));
                }
                catch (MongoQueryException ex) when(ex.Message.Contains("17406"))
                {
                    throw new DomainException(T.Get("common.resultTooLarge"));
                }
            }
        }
Esempio n. 21
0
 public Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, ClrQuery query, SearchScope scope)
 {
     if (scope == SearchScope.All)
     {
         return(collectionAll.QueryAsync(app, schema, query));
     }
     else
     {
         return(collectionPublished.QueryAsync(app, schema, query));
     }
 }
Esempio n. 22
0
 private static bool IsSatisfiedByIndex(ClrQuery query)
 {
     return(query.Sort?.All(x => x.Path.ToString() == "mt" && x.Order == SortOrder.Descending) == true);
 }
        public async Task <IResultList <IAssetEntity> > QueryAsync(Guid appId, Guid?parentId, ClrQuery query)
        {
            using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByQuery"))
            {
                try
                {
                    query = query.AdjustToModel();

                    var filter = query.BuildFilter(appId, parentId);

                    var assetCount = Collection.Find(filter).CountDocumentsAsync();
                    var assetItems =
                        Collection.Find(filter)
                        .AssetTake(query)
                        .AssetSkip(query)
                        .AssetSort(query)
                        .ToListAsync();

                    await Task.WhenAll(assetItems, assetCount);

                    return(ResultList.Create <IAssetEntity>(assetCount.Result, assetItems.Result));
                }
                catch (MongoQueryException ex)
                {
                    if (ex.Message.Contains("17406"))
                    {
                        throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items.");
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
        private async Task <IResultList <IAssetEntity> > QueryAsync(DomainId?parentId, ClrQuery query)
        {
            query.Top = 1000;

            query.Skip = 100;

            query.Sort = new List <SortNode>
            {
                new SortNode("LastModified", SortOrder.Descending)
            };

            var assets = await _.AssetRepository.QueryAsync(_.RandomAppId(), parentId, Q.Empty.WithQuery(query));

            return(assets);
        }
Esempio n. 25
0
 public static IFindFluent <MongoAssetEntity, MongoAssetEntity> AssetSkip(this IFindFluent <MongoAssetEntity, MongoAssetEntity> cursor, ClrQuery query)
 {
     return(cursor.Skip(query));
 }
 private Task <IResultList <IContentEntity> > QueryCoreAsync(Context context, ISchemaEntity schema, ClrQuery query)
 {
     return(contentRepository.QueryAsync(context.App, schema, GetStatus(context), context.IsFrontendClient, query, WithDraft(context)));
 }
Esempio n. 27
0
        public async Task <IResultList <IContentEntity> > DoAsync(IAppEntity app, ISchemaEntity schema, ClrQuery query, Status[]?status, bool inDraft, bool includeDraft = true)
        {
            Guard.NotNull(app);
            Guard.NotNull(schema);
            Guard.NotNull(query);

            try
            {
                query = query.AdjustToModel(schema.SchemaDef, inDraft);

                List <Guid>?fullTextIds = null;

                if (!string.IsNullOrWhiteSpace(query.FullText))
                {
                    fullTextIds = await indexer.SearchAsync(query.FullText, app, schema.Id, inDraft?Scope.Draft : Scope.Published);

                    if (fullTextIds?.Count == 0)
                    {
                        return(ResultList.CreateFrom <IContentEntity>(0));
                    }
                }

                var filter = CreateFilter(schema.Id, fullTextIds, status, query);

                var contentCount = Collection.Find(filter).CountDocumentsAsync();
                var contentItems =
                    Collection.Find(filter)
                    .WithoutDraft(includeDraft)
                    .QueryLimit(query)
                    .QuerySkip(query)
                    .QuerySort(query)
                    .ToListAsync();

                await Task.WhenAll(contentItems, contentCount);

                foreach (var entity in contentItems.Result)
                {
                    entity.ParseData(schema.SchemaDef, serializer);
                }

                return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result));
            }
            catch (MongoQueryException ex)
            {
                if (ex.Message.Contains("17406"))
                {
                    throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items.");
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 28
0
        public static IFindFluent <T, T> QueryLimit <T>(this IFindFluent <T, T> cursor, ClrQuery query)
        {
            if (query.Take < long.MaxValue)
            {
                cursor = cursor.Limit((int)query.Take);
            }

            return(cursor);
        }
Esempio n. 29
0
 public static (FilterDefinition <TDocument>?Filter, bool Last) BuildFilter <TDocument>(this ClrQuery query, bool supportsSearch = true)
 {
     if (query.FullText != null)
Esempio n. 30
0
        public async Task <IResultList <IContentEntity> > QueryAsync(ISchemaEntity schema, ClrQuery query, List <Guid> ids, Status[] status, bool inDraft, bool includeDraft = true)
        {
            try
            {
                query = query.AdjustToModel(schema.SchemaDef, inDraft);

                var filter = query.ToFilter(schema.Id, ids, status);

                var contentCount = Collection.Find(filter).CountDocumentsAsync();
                var contentItems =
                    Collection.Find(filter)
                    .WithoutDraft(includeDraft)
                    .ContentTake(query)
                    .ContentSkip(query)
                    .ContentSort(query)
                    .ToListAsync();

                await Task.WhenAll(contentItems, contentCount);

                foreach (var entity in contentItems.Result)
                {
                    entity.ParseData(schema.SchemaDef, serializer);
                }

                return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result));
            }
            catch (MongoQueryException ex)
            {
                if (ex.Message.Contains("17406"))
                {
                    throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items.");
                }
                else
                {
                    throw;
                }
            }
        }