public static AutoIndexDefinition GetAutoIndexDefinition(AutoIndexDefinitionBaseServerSide 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(AutoIndexDefinitionBaseServerSide 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 FaultyAutoIndexDefinition(string name, HashSet <string> collections, IndexLockMode lockMode, IndexPriority priority, IndexState state, IndexField[] mapFields, AutoIndexDefinitionBaseServerSide definition) : base(name, collections, lockMode, priority, state, mapFields, definition.Version, definition.DeploymentMode, definition.ClusterState) { Definition = definition; }
public FaultyInMemoryIndex(Exception e, string name, IndexingConfiguration configuration, AutoIndexDefinitionBaseServerSide 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, AutoIndexDefinitionBaseServerSide 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; } 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 static PutAutoIndexCommand Create(AutoIndexDefinitionBaseServerSide definition, string databaseName, string raftRequestId, IndexDeploymentMode mode) { var indexType = GetAutoIndexType(definition); return(new PutAutoIndexCommand(GetAutoIndexDefinition(definition, indexType), databaseName, raftRequestId, mode, SystemTime.UtcNow)); }
public void ExtendMappingBasedOn(AutoIndexDefinitionBaseServerSide 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, hasHighlighting : queryField.HasHighlighting || indexField.Indexing.HasFlag(AutoFieldIndexing.Highlighting), hasSuggestions : queryField.HasSuggestions || indexField.HasSuggestions, 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), hasHighlighting: indexField.Indexing.HasFlag(AutoFieldIndexing.Highlighting), hasSuggestions: indexField.HasSuggestions, spatial: indexField.Spatial)); } } } }