public void ExtendMappingBasedOn(AutoIndexDefinitionBase definitionOfExistingIndex) { Debug.Assert(definitionOfExistingIndex is AutoMapIndexDefinition || definitionOfExistingIndex is AutoMapReduceIndexDefinition, "Dynamic queries are handled only by auto indexes"); switch (definitionOfExistingIndex) { case AutoMapIndexDefinition def: Update(MapFields, def.MapFields, isGroupBy: false); break; case AutoMapReduceIndexDefinition def: Update(MapFields, def.MapFields, isGroupBy: false); Update(GroupByFields, def.GroupByFields, isGroupBy: true); break; } void Update <T>(Dictionary <string, DynamicQueryMappingItem> fields, Dictionary <string, T> indexFields, bool isGroupBy) where T : IndexFieldBase { foreach (var f in indexFields.Values) { var indexField = f.As <AutoIndexField>(); if (fields.TryGetValue(indexField.Name, out var queryField)) { var isFullTextSearch = queryField.IsFullTextSearch || indexField.Indexing.HasFlag(AutoFieldIndexing.Search); var isExactSearch = queryField.IsExactSearch || indexField.Indexing.HasFlag(AutoFieldIndexing.Exact); var field = isGroupBy == false ? DynamicQueryMappingItem.Create( queryField.Name, queryField.AggregationOperation, isFullTextSearch : isFullTextSearch, isExactSearch : isExactSearch, spatial : queryField.Spatial ?? indexField.Spatial) : DynamicQueryMappingItem.CreateGroupBy( queryField.Name, queryField.GroupByArrayBehavior, isSpecifiedInWhere: queryField.IsSpecifiedInWhere, isFullTextSearch: isFullTextSearch, isExactSearch: isExactSearch); fields[queryField.Name] = field; } else { if (isGroupBy) { throw new InvalidOperationException("Cannot create new GroupBy field when extending mapping"); } fields.Add(indexField.Name, DynamicQueryMappingItem.Create( new QueryFieldName(indexField.Name, indexField.HasQuotedName), indexField.Aggregation, isFullTextSearch: indexField.Indexing.HasFlag(AutoFieldIndexing.Search), isExactSearch: indexField.Indexing.HasFlag(AutoFieldIndexing.Exact), spatial: indexField.Spatial)); } } } }
private void HandleAutoIndexChange(string name, AutoIndexDefinitionBase definition) { var creationOptions = IndexCreationOptions.Create; var existingIndex = GetIndex(name); IndexDefinitionCompareDifferences differences = IndexDefinitionCompareDifferences.None; if (existingIndex != null) { creationOptions = GetIndexCreationOptions(definition, existingIndex, out differences); } if (creationOptions == IndexCreationOptions.Noop) { Debug.Assert(existingIndex != null); return; } if (creationOptions == IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex || creationOptions == IndexCreationOptions.Update) { Debug.Assert(existingIndex != null); if ((differences & IndexDefinitionCompareDifferences.LockMode) != 0) { existingIndex.SetLock(definition.LockMode); } if ((differences & IndexDefinitionCompareDifferences.Priority) != 0) { existingIndex.SetPriority(definition.Priority); } existingIndex.Update(definition, existingIndex.Configuration); return; } Index index; if (definition is AutoMapIndexDefinition) { index = AutoMapIndex.CreateNew((AutoMapIndexDefinition)definition, _documentDatabase); } else if (definition is AutoMapReduceIndexDefinition) { index = AutoMapReduceIndex.CreateNew((AutoMapReduceIndexDefinition)definition, _documentDatabase); } else { throw new NotImplementedException($"Unknown index definition type: {definition.GetType().FullName}"); } CreateIndexInternal(index); }
public static AutoIndexDefinition GetAutoIndexDefinition(AutoIndexDefinitionBase definition, IndexType indexType) { Debug.Assert(indexType == IndexType.AutoMap || indexType == IndexType.AutoMapReduce); return(new AutoIndexDefinition { Collection = definition.Collections.First(), MapFields = CreateFields(definition.MapFields.ToDictionary(x => x.Key, x => x.Value.As <AutoIndexField>())), GroupByFields = indexType == IndexType.AutoMap ? null : CreateFields(((AutoMapReduceIndexDefinition)definition).GroupByFields), Priority = definition.Priority, Name = definition.Name, Type = indexType }); }
public static IndexType GetAutoIndexType(AutoIndexDefinitionBase definition) { var indexType = IndexType.None; if (definition is AutoMapIndexDefinition) { indexType = IndexType.AutoMap; } if (definition is AutoMapReduceIndexDefinition) { indexType = IndexType.AutoMapReduce; } if (indexType == IndexType.None) { throw new RachisApplyException($"Invalid definition type: {definition.GetType()}"); } return(indexType); }
public void ExtendMappingBasedOn(AutoIndexDefinitionBase definitionOfExistingIndex) { Debug.Assert(definitionOfExistingIndex is AutoMapIndexDefinition || definitionOfExistingIndex is AutoMapReduceIndexDefinition, "Dynamic queries are handled only by auto indexes"); switch (definitionOfExistingIndex) { case AutoMapIndexDefinition def: Update(MapFields, def.MapFields); break; case AutoMapReduceIndexDefinition def: Update(MapFields, def.MapFields); Update(GroupByFields, def.GroupByFields); break; } void Update <T>(Dictionary <string, DynamicQueryMappingItem> mappingFields, Dictionary <string, T> indexFields) where T : IndexFieldBase { foreach (var f in indexFields.Values) { var indexField = f.As <AutoIndexField>(); if (mappingFields.TryGetValue(indexField.Name, out var queryField)) { mappingFields[queryField.Name] = DynamicQueryMappingItem.Create(queryField.Name, queryField.AggregationOperation, isFullTextSearch: queryField.IsFullTextSearch || indexField.Indexing.HasFlag(AutoFieldIndexing.Search), isExactSearch: queryField.IsExactSearch || indexField.Indexing.HasFlag(AutoFieldIndexing.Exact), spatial: queryField.Spatial ?? indexField.Spatial); } else { mappingFields.Add(indexField.Name, DynamicQueryMappingItem.Create(new QueryFieldName(indexField.Name, indexField.HasQuotedName), indexField.Aggregation, isFullTextSearch: indexField.Indexing.HasFlag(AutoFieldIndexing.Search), isExactSearch: indexField.Indexing.HasFlag(AutoFieldIndexing.Exact), spatial: indexField.Spatial)); } } } }
public static PutAutoIndexCommand Create(AutoIndexDefinitionBase definition, string databaseName) { var indexType = IndexType.None; var map = definition as AutoMapIndexDefinition; if (map != null) { indexType = IndexType.AutoMap; } var reduce = definition as AutoMapReduceIndexDefinition; if (reduce != null) { indexType = IndexType.AutoMapReduce; } if (indexType == IndexType.None) { throw new NotSupportedException("Invalid definition type: " + definition.GetType()); } return(new PutAutoIndexCommand(GetAutoIndexDefinition(definition, indexType), databaseName)); }
public static PutAutoIndexCommand Create(AutoIndexDefinitionBase definition, string databaseName, string raftRequestId) { var indexType = GetAutoIndexType(definition); return(new PutAutoIndexCommand(GetAutoIndexDefinition(definition, indexType), databaseName, raftRequestId)); }
public FaultyInMemoryIndex(Exception e, string name, IndexingConfiguration configuration, AutoIndexDefinitionBase definition) : this(e, configuration, new FaultyAutoIndexDefinition(name, new HashSet <string> { "@FaultyIndexes" }, IndexLockMode.Unlock, IndexPriority.Normal, IndexState.Normal, new IndexField[0], definition)) { }
internal DynamicQueryMatchResult ConsiderUsageOfIndex(DynamicQueryMapping query, AutoIndexDefinitionBase definition, List <Explanation> explanations = null) { var collection = query.ForCollection; var indexName = definition.Name; if (definition.Collections.Contains(collection) == false) { explanations?.Add(new Explanation(indexName, definition.Collections.Count == 0 ? "Query is specific for collection, but the index searches across all of them, may result in a different type being returned." : $"Index does not apply to collection '{collection}'")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Failure)); } if (definition.Collections.Count > 1) // we only allow indexes with a single entity name { explanations?.Add(new Explanation(indexName, "Index contains more than a single entity name, may result in a different type being returned.")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Failure)); } var index = _indexStore.GetIndex(definition.Name); if (index == null) { return(new DynamicQueryMatchResult(definition.Name, DynamicQueryMatchType.Failure)); } var state = index.State; bool isInvalidStats; try { isInvalidStats = index.IsInvalidIndex(); } catch (OperationCanceledException) { return(new DynamicQueryMatchResult(definition.Name, DynamicQueryMatchType.Failure)); } if (state == IndexState.Error || state == IndexState.Disabled || isInvalidStats) { explanations?.Add(new Explanation(indexName, $"Cannot do dynamic queries on disabled index or index with errors (index name = {indexName})")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Failure)); } var currentBestState = DynamicQueryMatchType.Complete; foreach (var field in query.MapFields.Values) { if (definition.TryGetField(field.Name, out var indexField)) { if (field.IsFullTextSearch && indexField.Indexing.HasFlag(AutoFieldIndexing.Search) == false) { explanations?.Add(new Explanation(indexName, $"The following field is not searchable {indexField.Name}, while the query needs to search() on it")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Partial)); } if (field.HasHighlighting && indexField.Indexing.HasFlag(AutoFieldIndexing.Highlighting) == false) { explanations?.Add(new Explanation(indexName, $"The following field does not have highlighting {indexField.Name}, while the query needs to do highlight() on it")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Partial)); } if (field.IsExactSearch && indexField.Indexing.HasFlag(AutoFieldIndexing.Exact) == false) { explanations?.Add(new Explanation(indexName, $"The following field is not exactable {indexField.Name}, while the query needs to perform exact() on it")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Partial)); } if (field.Spatial != null) { if (field.Spatial.Equals(indexField.Spatial) == false) { explanations?.Add(new Explanation(indexName, $"The following field is not a spatial field {indexField.Name}, while the query needs to perform spatial() on it")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Failure)); } } if (field.HasSuggestions && indexField.HasSuggestions == false) { explanations?.Add(new Explanation(indexName, $"The following field does not have suggestions enabled {indexField.Name}, while the query needs to perform suggest() on it")); return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Partial)); } } else { explanations?.Add(new Explanation(indexName, $"The following field is missing: {field.Name}")); currentBestState = DynamicQueryMatchType.Partial; } } if (currentBestState == DynamicQueryMatchType.Complete && state == IndexState.Idle) { currentBestState = DynamicQueryMatchType.CompleteButIdle; explanations?.Add(new Explanation(indexName, $"The index (name = {indexName}) is idle. The preference is for active indexes - making a complete match but marking the index is idle")); } if (currentBestState != DynamicQueryMatchType.Failure && query.IsGroupBy) { var bestMapReduceMatch = AssertMapReduceFields(query, (AutoMapReduceIndexDefinition)definition, currentBestState, explanations); if (bestMapReduceMatch != DynamicQueryMatchType.Complete) { return(new DynamicQueryMatchResult(indexName, bestMapReduceMatch)); } } long lastMappedEtagFor; try { lastMappedEtagFor = index.GetLastMappedEtagFor(collection); } catch (OperationCanceledException) { // the index was disposed while we were reading it, just ignore it // probably dynamic index that was disposed by the auto cleaner return(new DynamicQueryMatchResult(indexName, DynamicQueryMatchType.Failure)); } return(new DynamicQueryMatchResult(indexName, currentBestState) { LastMappedEtag = lastMappedEtagFor, NumberOfMappedFields = definition.MapFields.Count }); }
public FaultyAutoIndexDefinition(string name, HashSet <string> collections, IndexLockMode lockMode, IndexPriority priority, IndexState state, IndexField[] mapFields, AutoIndexDefinitionBase definition) : base(name, collections, lockMode, priority, state, mapFields, definition.Version) { Definition = definition; }