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 static Dictionary <string, DynamicQueryMappingItem> CreateGroupByFields(IndexQueryServerSide query, Dictionary <string, DynamicQueryMappingItem> mapFields) { var groupByFields = query.Metadata.GroupBy; if (query.Metadata.SelectFields != null) { foreach (var field in query.Metadata.SelectFields) { if (field.IsGroupByKey) { continue; } var fieldName = field.Name; if (mapFields.TryGetValue(fieldName, out var existingField) == false) { switch (field.AggregationOperation) { case AggregationOperation.None: break; case AggregationOperation.Count: case AggregationOperation.Sum: mapFields.Add(fieldName, DynamicQueryMappingItem.Create(fieldName, field.AggregationOperation)); break; default: ThrowUnknownAggregationOperation(field.AggregationOperation); break; } } else if (field.AggregationOperation != AggregationOperation.None) { existingField.SetAggregation(field.AggregationOperation); } } } var result = new Dictionary <string, DynamicQueryMappingItem>(groupByFields.Length, StringComparer.Ordinal); for (int i = 0; i < groupByFields.Length; i++) { var groupByField = groupByFields[i]; result[groupByField.Name] = DynamicQueryMappingItem.CreateGroupBy(groupByField.Name, groupByField.GroupByArrayBehavior, query.Metadata.WhereFields); mapFields.Remove(groupByField.Name); // ensure we don't have duplicated group by fields } return(result); }
public static DynamicQueryMapping Create(Index index) { if (index.Type.IsAuto() == false) { throw new InvalidOperationException(); } var mapping = new DynamicQueryMapping { ForCollection = index.Collections.First(), MapFields = new Dictionary <string, DynamicQueryMappingItem>(StringComparer.Ordinal) }; var definition = (AutoIndexDefinitionBase)index.Definition; foreach (var field in definition.MapFields) { var autoField = (AutoIndexField)field.Value; mapping.MapFields[field.Key] = DynamicQueryMappingItem.Create( new QueryFieldName(autoField.Name, autoField.HasQuotedName), autoField.Aggregation, isFullTextSearch: autoField.Indexing.HasFlag(AutoFieldIndexing.Search), isExactSearch: autoField.Indexing.HasFlag(AutoFieldIndexing.Exact), hasHighlighting: autoField.Indexing.HasFlag(AutoFieldIndexing.Highlighting), hasSuggestions: autoField.HasSuggestions, spatial: autoField.Spatial); } if (index.Type.IsMapReduce()) { mapping.IsGroupBy = true; var mapReduceDefinition = (AutoMapReduceIndexDefinition)definition; mapping.GroupByFields = new Dictionary <string, DynamicQueryMappingItem>(StringComparer.Ordinal); foreach (var field in mapReduceDefinition.GroupByFields) { var autoField = field.Value; mapping.GroupByFields[field.Key] = DynamicQueryMappingItem.CreateGroupBy( new QueryFieldName(autoField.Name, autoField.HasQuotedName), autoField.GroupByArrayBehavior, isSpecifiedInWhere: true, isFullTextSearch: autoField.Indexing.HasFlag(AutoFieldIndexing.Search), isExactSearch: autoField.Indexing.HasFlag(AutoFieldIndexing.Exact)); } } return(mapping); }