private void GetTimeSeriesQueryString(DocumentDatabase database, DocumentsOperationContext context, out IncludeTimeSeriesCommand includeTimeSeries) { includeTimeSeries = null; var timeSeriesNames = GetStringValuesQueryString("timeseries", required: false); if (timeSeriesNames.Count == 0) { return; } var fromList = GetStringValuesQueryString("from", required: false); var toList = GetStringValuesQueryString("to", required: false); if (timeSeriesNames.Count != fromList.Count || fromList.Count != toList.Count) { throw new InvalidOperationException("Parameters 'timeseriesNames', 'fromList' and 'toList' must be of equal length. " + $"Got : timeseriesNames.Count = {timeSeriesNames.Count}, fromList.Count = {fromList.Count}, toList.Count = {toList.Count}."); } var hs = new HashSet <TimeSeriesRange>(TimeSeriesRangeComparer.Instance); for (int i = 0; i < timeSeriesNames.Count; i++) { hs.Add(new TimeSeriesRange { Name = timeSeriesNames[i], From = string.IsNullOrEmpty(fromList[i]) ? DateTime.MinValue : TimeSeriesHandler.ParseDate(fromList[i], "from"), To = string.IsNullOrEmpty(toList[i]) ? DateTime.MaxValue : TimeSeriesHandler.ParseDate(toList[i], "to") }); } includeTimeSeries = new IncludeTimeSeriesCommand(context, new Dictionary <string, HashSet <TimeSeriesRange> > { { string.Empty, hs } }); }
public override void AddTimeSeriesIncludes(IncludeTimeSeriesCommand includeTimeSeriesCommand) { throw new NotSupportedException(); }
private void GetTimeSeriesQueryString(DocumentDatabase database, DocumentsOperationContext context, out IncludeTimeSeriesCommand includeTimeSeries) { includeTimeSeries = null; var timeSeriesNames = GetStringValuesQueryString("timeseries", required: false); var timeSeriesTimeNames = GetStringValuesQueryString("timeseriestime", required: false); var timeSeriesCountNames = GetStringValuesQueryString("timeseriescount", required: false); if (timeSeriesNames.Count == 0 && timeSeriesTimeNames.Count == 0 && timeSeriesCountNames.Count == 0) { return; } if (timeSeriesNames.Count > 1 && timeSeriesNames.Contains(Constants.TimeSeries.All)) { throw new InvalidOperationException($"Cannot have more than one include on '{Constants.TimeSeries.All}'."); } if (timeSeriesTimeNames.Count > 1 && timeSeriesTimeNames.Contains(Constants.TimeSeries.All)) { throw new InvalidOperationException($"Cannot have more than one include on '{Constants.TimeSeries.All}'."); } if (timeSeriesCountNames.Count > 1 && timeSeriesCountNames.Contains(Constants.TimeSeries.All)) { throw new InvalidOperationException($"Cannot have more than one include on '{Constants.TimeSeries.All}'."); } var fromList = GetStringValuesQueryString("from", required: false); var toList = GetStringValuesQueryString("to", required: false); if (timeSeriesNames.Count != fromList.Count || fromList.Count != toList.Count) { throw new InvalidOperationException("Parameters 'timeseriesNames', 'fromList' and 'toList' must be of equal length. " + $"Got : timeseriesNames.Count = {timeSeriesNames.Count}, fromList.Count = {fromList.Count}, toList.Count = {toList.Count}."); } var timeTypeList = GetStringValuesQueryString("timeType", required: false); var timeValueList = GetStringValuesQueryString("timeValue", required: false); var timeUnitList = GetStringValuesQueryString("timeUnit", required: false); if (timeSeriesTimeNames.Count != timeTypeList.Count || timeTypeList.Count != timeValueList.Count || timeValueList.Count != timeUnitList.Count) { throw new InvalidOperationException($"Parameters '{nameof(timeSeriesTimeNames)}', '{nameof(timeTypeList)}', '{nameof(timeValueList)}' and '{nameof(timeUnitList)}' must be of equal length. " + $"Got : {nameof(timeSeriesTimeNames)}.Count = {timeSeriesTimeNames.Count}, {nameof(timeTypeList)}.Count = {timeTypeList.Count}, {nameof(timeValueList)}.Count = {timeValueList.Count}, {nameof(timeUnitList)}.Count = {timeUnitList.Count}."); } var countTypeList = GetStringValuesQueryString("countType", required: false); var countValueList = GetStringValuesQueryString("countValue", required: false); if (timeSeriesCountNames.Count != countTypeList.Count || countTypeList.Count != countValueList.Count) { throw new InvalidOperationException($"Parameters '{nameof(timeSeriesCountNames)}', '{nameof(countTypeList)}', '{nameof(countValueList)}' must be of equal length. " + $"Got : {nameof(timeSeriesCountNames)}.Count = {timeSeriesCountNames.Count}, {nameof(countTypeList)}.Count = {countTypeList.Count}, {nameof(countValueList)}.Count = {countValueList.Count}."); } var hs = new HashSet <AbstractTimeSeriesRange>(AbstractTimeSeriesRangeComparer.Instance); for (int i = 0; i < timeSeriesNames.Count; i++) { hs.Add(new TimeSeriesRange { Name = timeSeriesNames[i], From = string.IsNullOrEmpty(fromList[i]) ? DateTime.MinValue : TimeSeriesHandler.ParseDate(fromList[i], "from"), To = string.IsNullOrEmpty(toList[i]) ? DateTime.MaxValue : TimeSeriesHandler.ParseDate(toList[i], "to") }); } for (int i = 0; i < timeSeriesTimeNames.Count; i++) { var timeValueUnit = (TimeValueUnit)Enum.Parse(typeof(TimeValueUnit), timeUnitList[i]); if (timeValueUnit == TimeValueUnit.None) { throw new InvalidOperationException($"Got unexpected {nameof(TimeValueUnit)} '{nameof(TimeValueUnit.None)}'. Only the following are supported: '{nameof(TimeValueUnit.Second)}' or '{nameof(TimeValueUnit.Month)}'."); } if (int.TryParse(timeValueList[i], out int res) == false) { throw new InvalidOperationException($"Could not parse timeseries time range value."); } hs.Add(new TimeSeriesTimeRange { Name = timeSeriesTimeNames[i], Type = (TimeSeriesRangeType)Enum.Parse(typeof(TimeSeriesRangeType), timeTypeList[i]), Time = timeValueUnit == TimeValueUnit.Second ? TimeValue.FromSeconds(res) : TimeValue.FromMonths(res) }); } for (int i = 0; i < timeSeriesCountNames.Count; i++) { if (int.TryParse(countValueList[i], out int res) == false) { throw new InvalidOperationException($"Could not parse timeseries count value."); } hs.Add(new TimeSeriesCountRange { Name = timeSeriesCountNames[i], Type = (TimeSeriesRangeType)Enum.Parse(typeof(TimeSeriesRangeType), countTypeList[i]), Count = res }); } includeTimeSeries = new IncludeTimeSeriesCommand(context, new Dictionary <string, HashSet <AbstractTimeSeriesRange> > { { string.Empty, hs } }); }
public override void AddTimeSeriesIncludes(IncludeTimeSeriesCommand includeTimeSeriesCommand) { _timeSeriesIncludes = includeTimeSeriesCommand.Results; }
public abstract void AddTimeSeriesIncludes(IncludeTimeSeriesCommand command);
private void ExecuteCollectionQuery(QueryResultServerSide <Document> resultToFill, IndexQueryServerSide query, string collection, QueryOperationContext context, bool pulseReadingTransaction, CancellationToken cancellationToken) { using (var queryScope = query.Timings?.For(nameof(QueryTimingsScope.Names.Query))) { QueryTimingsScope gatherScope = null; QueryTimingsScope fillScope = null; if (queryScope != null && query.Metadata.Includes?.Length > 0) { var includesScope = queryScope.For(nameof(QueryTimingsScope.Names.Includes), start: false); gatherScope = includesScope.For(nameof(QueryTimingsScope.Names.Gather), start: false); fillScope = includesScope.For(nameof(QueryTimingsScope.Names.Fill), start: false); } // we optimize for empty queries without sorting options, appending CollectionIndexPrefix to be able to distinguish index for collection vs. physical index resultToFill.IsStale = false; resultToFill.LastQueryTime = DateTime.MinValue; resultToFill.IndexTimestamp = DateTime.MinValue; resultToFill.IncludedPaths = query.Metadata.Includes; var fieldsToFetch = new FieldsToFetch(query, null); var includeDocumentsCommand = new IncludeDocumentsCommand(Database.DocumentsStorage, context.Documents, query.Metadata.Includes, fieldsToFetch.IsProjection); var includeCompareExchangeValuesCommand = IncludeCompareExchangeValuesCommand.ExternalScope(context, query.Metadata.CompareExchangeValueIncludes); var totalResults = new Reference <int>(); IEnumerator <Document> enumerator; if (pulseReadingTransaction == false) { var documents = new CollectionQueryEnumerable(Database, Database.DocumentsStorage, fieldsToFetch, collection, query, queryScope, context.Documents, includeDocumentsCommand, includeCompareExchangeValuesCommand, totalResults); enumerator = documents.GetEnumerator(); } else { enumerator = new PulsedTransactionEnumerator <Document, CollectionQueryResultsIterationState>(context.Documents, state => { query.Start = state.Start; query.PageSize = state.Take; var documents = new CollectionQueryEnumerable(Database, Database.DocumentsStorage, fieldsToFetch, collection, query, queryScope, context.Documents, includeDocumentsCommand, includeCompareExchangeValuesCommand, totalResults); return(documents); }, new CollectionQueryResultsIterationState(context.Documents, Database.Configuration.Databases.PulseReadTransactionLimit) { Start = query.Start, Take = query.PageSize }); } IncludeCountersCommand includeCountersCommand = null; IncludeTimeSeriesCommand includeTimeSeriesCommand = null; if (query.Metadata.CounterIncludes != null) { includeCountersCommand = new IncludeCountersCommand( Database, context.Documents, query.Metadata.CounterIncludes.Counters); } if (query.Metadata.TimeSeriesIncludes != null) { includeTimeSeriesCommand = new IncludeTimeSeriesCommand( context.Documents, query.Metadata.TimeSeriesIncludes.TimeSeries); } try { using (enumerator) { while (enumerator.MoveNext()) { var document = enumerator.Current; cancellationToken.ThrowIfCancellationRequested(); resultToFill.AddResult(document); using (gatherScope?.Start()) { includeDocumentsCommand.Gather(document); includeCompareExchangeValuesCommand?.Gather(document); } includeCountersCommand?.Fill(document); includeTimeSeriesCommand?.Fill(document); } } } catch (Exception e) { if (resultToFill.SupportsExceptionHandling == false) { throw; } resultToFill.HandleException(e); } using (fillScope?.Start()) { includeDocumentsCommand.Fill(resultToFill.Includes); includeCompareExchangeValuesCommand.Materialize(); } if (includeCompareExchangeValuesCommand != null) { resultToFill.AddCompareExchangeValueIncludes(includeCompareExchangeValuesCommand); } if (includeCountersCommand != null) { resultToFill.AddCounterIncludes(includeCountersCommand); } if (includeTimeSeriesCommand != null) { resultToFill.AddTimeSeriesIncludes(includeTimeSeriesCommand); } resultToFill.RegisterTimeSeriesFields(query, fieldsToFetch); resultToFill.TotalResults = (totalResults.Value == 0 && resultToFill.Results.Count != 0) ? -1 : totalResults.Value; if (query.Offset != null || query.Limit != null) { if (resultToFill.TotalResults == -1) { resultToFill.CappedMaxResults = query.Limit ?? -1; } else { resultToFill.CappedMaxResults = Math.Min( query.Limit ?? int.MaxValue, resultToFill.TotalResults - (query.Offset ?? 0) ); } } } }