Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }