public async Task <(Index Index, bool HasCreatedAutoIndex)> CreateAutoIndexIfNeeded(IndexQueryServerSide query, bool createAutoIndexIfNoMatchIsFound, TimeSpan?customStalenessWaitTimeout, CancellationToken token) { var map = DynamicQueryMapping.Create(query); bool hasCreatedAutoIndex = false; Index index; while (TryMatchExistingIndexToQuery(map, out index) == false) { if (createAutoIndexIfNoMatchIsFound == false) { throw new IndexDoesNotExistException("Could not find index for a given query."); } var definition = map.CreateAutoIndexDefinition(); index = await _indexStore.CreateIndex(definition, RaftIdGenerator.NewId()); if (index == null) { // the index was deleted, we'll try to find a better match (replaced by a wider index) continue; } hasCreatedAutoIndex = true; if (query.WaitForNonStaleResultsTimeout.HasValue == false) { query.WaitForNonStaleResultsTimeout = customStalenessWaitTimeout ?? TimeSpan.FromSeconds(15); } var t = CleanupSupersededAutoIndexes(index, map, RaftIdGenerator.NewId(), token) .ContinueWith(task => { if (task.Exception != null) { if (token.IsCancellationRequested) { return; } if (_indexStore.Logger.IsInfoEnabled) { _indexStore.Logger.Info("Failed to delete superseded indexes for index " + index.Name); } } }, token); if (query.WaitForNonStaleResults && Database.Configuration.Indexing.TimeToWaitBeforeDeletingAutoIndexMarkedAsIdle.AsTimeSpan == TimeSpan.Zero) { await t; // this is used in testing, mainly } break; } return(index, hasCreatedAutoIndex); }
public List <DynamicQueryToIndexMatcher.Explanation> ExplainIndexSelection(IndexQueryServerSide query, DocumentsOperationContext docsContext) { var map = DynamicQueryMapping.Create(query); var explanations = new List <DynamicQueryToIndexMatcher.Explanation>(); var dynamicQueryToIndex = new DynamicQueryToIndexMatcher(_indexStore); dynamicQueryToIndex.Match(map, docsContext, explanations); return(explanations); }
public List <DynamicQueryToIndexMatcher.Explanation> ExplainIndexSelection(IndexQueryServerSide query, out string indexName) { var map = DynamicQueryMapping.Create(query); var explanations = new List <DynamicQueryToIndexMatcher.Explanation>(); var dynamicQueryToIndex = new DynamicQueryToIndexMatcher(_indexStore); var match = dynamicQueryToIndex.Match(map, explanations); indexName = match.IndexName; return(explanations); }
public List <DynamicQueryToIndexMatcher.Explanation> ExplainIndexSelection(string dynamicIndexName, IndexQueryServerSide query) { var collection = dynamicIndexName.Substring(DynamicIndexPrefix.Length); var map = DynamicQueryMapping.Create(collection, query); var explanations = new List <DynamicQueryToIndexMatcher.Explanation>(); var dynamicQueryToIndex = new DynamicQueryToIndexMatcher(_indexStore); dynamicQueryToIndex.Match(map, explanations); return(explanations); }
private Index MatchIndex(string dynamicIndexName, IndexQueryServerSide query, bool createAutoIndexIfNoMatchIsFound, out string collection) { collection = dynamicIndexName.Length == DynamicIndex.Length ? Constants.Indexing.AllDocumentsCollection : dynamicIndexName.Substring(DynamicIndexPrefix.Length); var map = DynamicQueryMapping.Create(collection, query); if (map.MapFields.Length == 0 && map.SortDescriptors.Length == 0 && map.GroupByFields.Length == 0) { return(null); // use collection query } Index index; if (TryMatchExistingIndexToQuery(map, out index) == false) { if (createAutoIndexIfNoMatchIsFound == false) { throw new IndexDoesNotExistsException("Could not find index for a given query."); } var definition = map.CreateAutoIndexDefinition(); var id = _indexStore.CreateIndex(definition); index = _indexStore.GetIndex(id); if (query.WaitForNonStaleResultsTimeout.HasValue == false) { query.WaitForNonStaleResultsTimeout = TimeSpan.FromSeconds(15); // allow new auto indexes to have some results } } EnsureValidQuery(query, map); return(index); }
private async Task <Index> MatchIndex(IndexQueryServerSide query, bool createAutoIndexIfNoMatchIsFound, TimeSpan?customStalenessWaitTimeout, DocumentsOperationContext docsContext, CancellationToken token) { Index index; if (query.Metadata.AutoIndexName != null) { index = _indexStore.GetIndex(query.Metadata.AutoIndexName); if (index != null) { return(index); } } var map = DynamicQueryMapping.Create(query); if (TryMatchExistingIndexToQuery(map, docsContext, out index) == false) { if (createAutoIndexIfNoMatchIsFound == false) { throw new IndexDoesNotExistException("Could not find index for a given query."); } var definition = map.CreateAutoIndexDefinition(); index = await _indexStore.CreateIndex(definition); if (query.WaitForNonStaleResultsTimeout.HasValue == false) { if (customStalenessWaitTimeout.HasValue) { query.WaitForNonStaleResultsTimeout = customStalenessWaitTimeout.Value; } else { query.WaitForNonStaleResultsTimeout = TimeSpan.FromSeconds(15); // allow new auto indexes to have some results } } var t = CleanupSupercededAutoIndexes(index, map, token) .ContinueWith(task => { if (task.Exception != null) { if (token.IsCancellationRequested) { return; } if (_indexStore.Logger.IsInfoEnabled) { _indexStore.Logger.Info("Failed to delete superceded indexes for index " + index.Name); } } }); if (query.WaitForNonStaleResults && Database.Configuration.Indexing.TimeToWaitBeforeDeletingAutoIndexMarkedAsIdle.AsTimeSpan == TimeSpan.Zero) { await t; // this is used in testing, mainly } } return(index); }
private async Task <(Index Index, string Collection)> MatchIndex(IndexQueryServerSide query, bool createAutoIndexIfNoMatchIsFound) { var collection = query.Metadata.CollectionName; if (query.Metadata.DynamicIndexName != null) { var previousIndex = _indexStore.GetIndex(query.Metadata.DynamicIndexName); if (previousIndex != null) { return(previousIndex, collection); } } if (query.Metadata.IsCollectionQuery) { return(null, collection); } var map = DynamicQueryMapping.Create(query); if (TryMatchExistingIndexToQuery(map, out Index index) == false) { if (createAutoIndexIfNoMatchIsFound == false) { throw new IndexDoesNotExistException("Could not find index for a given query."); } var definition = map.CreateAutoIndexDefinition(); var id = await _indexStore.CreateIndex(definition); index = _indexStore.GetIndex(id); var t = CleanupSupercededAutoIndexes(index, map) .ContinueWith(task => { if (task.Exception != null) { if (_token.Token.IsCancellationRequested) { return; } if (_indexStore.Logger.IsInfoEnabled) { _indexStore.Logger.Info("Failed to delete superceded indexes for index " + index.Name); } } }); if (query.WaitForNonStaleResults && _configuration.Indexing.TimeToWaitBeforeDeletingAutoIndexMarkedAsIdle.AsTimeSpan == TimeSpan.Zero) { await t; // this is used in testing, mainly } if (query.WaitForNonStaleResultsTimeout.HasValue == false) { query.WaitForNonStaleResultsTimeout = TimeSpan.FromSeconds(15); // allow new auto indexes to have some results } } return(index, collection); }