예제 #1
0
        public override async Task <IndexEntriesQueryResult> ExecuteIndexEntriesQuery(IndexQueryServerSide query, DocumentsOperationContext context, long?existingResultEtag, OperationCancelToken token)
        {
            var index = GetIndex(query.Metadata.IndexName);

            if (existingResultEtag.HasValue)
            {
                var etag = index.GetIndexEtag(query.Metadata);
                if (etag == existingResultEtag)
                {
                    return(IndexEntriesQueryResult.NotModifiedResult);
                }
            }

            using (QueryRunner.MarkQueryAsRunning(index.Name, query, token))
            {
                return(await index.IndexEntries(query, context, token));
            }
        }
예제 #2
0
        public override async Task <DocumentQueryResult> ExecuteQuery(IndexQueryServerSide query, DocumentsOperationContext documentsContext, long?existingResultEtag, OperationCancelToken token)
        {
            var index = GetIndex(query.Metadata.IndexName);

            if (query.Metadata.HasOrderByRandom == false && existingResultEtag.HasValue)
            {
                var etag = index.GetIndexEtag(query.Metadata);
                if (etag == existingResultEtag)
                {
                    return(DocumentQueryResult.NotModifiedResult);
                }
            }

            using (QueryRunner.MarkQueryAsRunning(index.Name, query, token))
            {
                return(await index.Query(query, documentsContext, token));
            }
        }
예제 #3
0
        private async Task <TResult> ExecuteQuery <TResult>(TResult final, IndexQueryServerSide query, DocumentsOperationContext documentsContext, long?existingResultEtag, OperationCancelToken token) where TResult : QueryResultServerSide <Document>
        {
            try
            {
                if (Database.ServerStore.Configuration.Core.FeaturesAvailability == FeaturesAvailability.Stable)
                {
                    FeaturesAvailabilityException.Throw("Graph Queries");
                }

                using (QueryRunner.MarkQueryAsRunning(Constants.Documents.Indexing.DummyGraphIndexName, query, token))
                    using (var timingScope = new QueryTimingsScope())
                    {
                        var qr = await GetQueryResults(query, documentsContext, existingResultEtag, token);

                        if (qr.NotModified)
                        {
                            final.NotModified = true;
                            return(final);
                        }
                        var q = query.Metadata.Query;

                        //TODO: handle order by, load,  clauses
                        IncludeDocumentsCommand idc = null;
                        if (q.Select == null && q.SelectFunctionBody.FunctionText == null)
                        {
                            HandleResultsWithoutSelect(documentsContext, qr.Matches, final);
                        }
                        else if (q.Select != null)
                        {
                            //TODO : investigate fields to fetch
                            var fieldsToFetch = new FieldsToFetch(query, null);
                            idc = new IncludeDocumentsCommand(Database.DocumentsStorage, documentsContext, query.Metadata.Includes, fieldsToFetch.IsProjection);

                            var resultRetriever = new GraphQueryResultRetriever(
                                q.GraphQuery,
                                Database,
                                query,
                                timingScope,
                                Database.DocumentsStorage,
                                documentsContext,
                                fieldsToFetch,
                                idc);

                            HashSet <ulong> alreadySeenProjections = null;
                            if (q.IsDistinct)
                            {
                                alreadySeenProjections = new HashSet <ulong>();
                            }
                            foreach (var match in qr.Matches)
                            {
                                if (match.Empty)
                                {
                                    continue;
                                }

                                var result = resultRetriever.ProjectFromMatch(match, documentsContext);
                                // ReSharper disable once PossibleNullReferenceException
                                if (q.IsDistinct && alreadySeenProjections.Add(result.DataHash) == false)
                                {
                                    continue;
                                }
                                final.AddResult(result);
                            }
                        }

                        if (idc == null)
                        {
                            idc = new IncludeDocumentsCommand(Database.DocumentsStorage, documentsContext, query.Metadata.Includes, isProjection: false);
                        }

                        if (query.Metadata.Includes?.Length > 0)
                        {
                            foreach (var result in final.Results)
                            {
                                idc.Gather(result);
                            }
                        }

                        idc.Fill(final.Includes);

                        final.TotalResults = final.Results.Count;

                        if (query.Limit != null || query.Offset != null)
                        {
                            final.CappedMaxResults = Math.Min(
                                query.Limit ?? int.MaxValue,
                                final.TotalResults - (query.Offset ?? 0)
                                );
                        }

                        final.IsStale    = qr.QueryPlan.IsStale;
                        final.ResultEtag = qr.QueryPlan.ResultEtag;
                        return(final);
                    }
            }
            catch (OperationCanceledException oce)
            {
                throw new OperationCanceledException($"Database:{Database} Query:{query.Metadata.Query} has been cancelled ", oce);
            }
        }