private static Sort GetSort(SortedField[] sortedFields) { if (sortedFields == null || sortedFields.Length == 0) { return(null); } return(new Sort(sortedFields.Select(x => { var sortOptions = SortOptions.String; if (x.Field == Constants.Indexing.Fields.IndexFieldScoreName) { return SortField.FIELD_SCORE; } if (InvariantCompare.IsPrefix(x.Field, Constants.Indexing.Fields.AlphaNumericFieldName, CompareOptions.None)) { var customFieldName = SortFieldHelper.ExtractName(x.Field); if (customFieldName.IsNullOrWhiteSpace()) { throw new InvalidOperationException("Alphanumeric sort: cannot figure out what field to sort on!"); } var anSort = new AlphaNumericComparatorSource(); return new SortField(customFieldName, anSort, x.Descending); } if (InvariantCompare.IsPrefix(x.Field, Constants.Indexing.Fields.RandomFieldName, CompareOptions.None)) { var customFieldName = SortFieldHelper.ExtractName(x.Field); if (customFieldName.IsNullOrWhiteSpace()) // truly random { return new RandomSortField(Guid.NewGuid().ToString()); } return new RandomSortField(customFieldName); } if (InvariantCompare.IsSuffix(x.Field, Constants.Indexing.Fields.RangeFieldSuffix, CompareOptions.None)) { sortOptions = SortOptions.NumericDouble; // TODO arek - it seems to be working fine with long values as well however needs to be verified } return new SortField(IndexField.ReplaceInvalidCharactersInFieldName(x.Field), (int)sortOptions, x.Descending); }).ToArray())); }
private static Sort GetSort(IndexQueryServerSide query, Func <string, SpatialField> getSpatialField) { var orderByFields = query.Metadata.OrderBy; if (orderByFields == null) { return(null); } var sort = new List <SortField>(); foreach (var field in orderByFields) { if (field.OrderingType == OrderByFieldType.Random) { string value = null; if (field.Arguments != null && field.Arguments.Length > 0) { value = field.Arguments[0].NameOrValue; } sort.Add(new RandomSortField(value)); continue; } if (field.OrderingType == OrderByFieldType.Score) { sort.Add(SortField.FIELD_SCORE); continue; } if (field.OrderingType == OrderByFieldType.Distance) { var spatialField = getSpatialField(field.Name); Point point; switch (field.Method) { case MethodType.Circle: var cLatitude = field.Arguments[1].GetDouble(query.QueryParameters); var cLongitude = field.Arguments[2].GetDouble(query.QueryParameters); point = spatialField.ReadPoint(cLatitude, cLongitude).GetCenter(); break; case MethodType.Wkt: var wkt = field.Arguments[0].GetString(query.QueryParameters); SpatialUnits?spatialUnits = null; if (field.Arguments.Length == 2) { spatialUnits = Enum.Parse <SpatialUnits>(field.Arguments[1].GetString(query.QueryParameters), ignoreCase: true); } point = spatialField.ReadShape(wkt, spatialUnits).GetCenter(); break; case MethodType.Point: var pLatitude = field.Arguments[0].GetDouble(query.QueryParameters); var pLongitude = field.Arguments[1].GetDouble(query.QueryParameters); point = spatialField.ReadPoint(pLatitude, pLongitude).GetCenter(); break; default: throw new ArgumentOutOfRangeException(); } var dsort = new SpatialDistanceFieldComparatorSource(spatialField, point); sort.Add(new SortField(field.Name, dsort, field.Ascending == false)); continue; } var fieldName = field.Name.Value; var sortOptions = SortField.STRING; switch (field.OrderingType) { case OrderByFieldType.AlphaNumeric: var anSort = new AlphaNumericComparatorSource(); sort.Add(new SortField(fieldName, anSort, field.Ascending == false)); continue; case OrderByFieldType.Long: sortOptions = SortField.LONG; fieldName = fieldName + Constants.Documents.Indexing.Fields.RangeFieldSuffixLong; break; case OrderByFieldType.Double: sortOptions = SortField.DOUBLE; fieldName = fieldName + Constants.Documents.Indexing.Fields.RangeFieldSuffixDouble; break; } sort.Add(new SortField(fieldName, sortOptions, field.Ascending == false)); } return(new Sort(sort.ToArray())); }
private IDisposable GetSort(IndexQueryServerSide query, Index index, Func <string, SpatialField> getSpatialField, DocumentsOperationContext documentsContext, out Sort sort) { sort = null; if (query.PageSize == 0) // no need to sort when counting only { return(null); } var orderByFields = query.Metadata.OrderBy; if (orderByFields == null) { if (query.Metadata.HasBoost == false && index.HasBoostedFields == false) { return(null); } sort = SortByFieldScore; return(null); } int sortIndex = 0; var sortArray = new ArraySegment <SortField>(ArrayPool <SortField> .Shared.Rent(orderByFields.Length), sortIndex, orderByFields.Length); foreach (var field in orderByFields) { if (field.OrderingType == OrderByFieldType.Random) { string value = null; if (field.Arguments != null && field.Arguments.Length > 0) { value = field.Arguments[0].NameOrValue; } sortArray[sortIndex++] = new RandomSortField(value); continue; } if (field.OrderingType == OrderByFieldType.Score) { if (field.Ascending) { sortArray[sortIndex++] = SortField.FIELD_SCORE; } else { sortArray[sortIndex++] = new SortField(null, 0, true); } continue; } if (field.OrderingType == OrderByFieldType.Distance) { var spatialField = getSpatialField(field.Name); int lastArgument; Point point; switch (field.Method) { case MethodType.Spatial_Circle: var cLatitude = field.Arguments[1].GetDouble(query.QueryParameters); var cLongitude = field.Arguments[2].GetDouble(query.QueryParameters); lastArgument = 2; point = spatialField.ReadPoint(cLatitude, cLongitude).GetCenter(); break; case MethodType.Spatial_Wkt: var wkt = field.Arguments[0].GetString(query.QueryParameters); SpatialUnits?spatialUnits = null; lastArgument = 1; if (field.Arguments.Length > 1) { spatialUnits = Enum.Parse <SpatialUnits>(field.Arguments[1].GetString(query.QueryParameters), ignoreCase: true); lastArgument = 2; } point = spatialField.ReadShape(wkt, spatialUnits).GetCenter(); break; case MethodType.Spatial_Point: var pLatitude = field.Arguments[0].GetDouble(query.QueryParameters); var pLongitude = field.Arguments[1].GetDouble(query.QueryParameters); lastArgument = 2; point = spatialField.ReadPoint(pLatitude, pLongitude).GetCenter(); break; default: throw new ArgumentOutOfRangeException(); } var roundTo = field.Arguments.Length > lastArgument ? field.Arguments[lastArgument].GetDouble(query.QueryParameters) : 0; var dsort = new SpatialDistanceFieldComparatorSource(spatialField, point, query, roundTo); sortArray[sortIndex++] = new SortField(field.Name, dsort, field.Ascending == false); continue; } var fieldName = field.Name.Value; var sortOptions = SortField.STRING; switch (field.OrderingType) { case OrderByFieldType.Custom: var cName = field.Arguments[0].NameOrValue; var cSort = new CustomComparatorSource(cName, _index.DocumentDatabase.Name, query); sortArray[sortIndex++] = new SortField(fieldName, cSort, field.Ascending == false); continue; case OrderByFieldType.AlphaNumeric: var anSort = new AlphaNumericComparatorSource(documentsContext); sortArray[sortIndex++] = new SortField(fieldName, anSort, field.Ascending == false); continue; case OrderByFieldType.Long: sortOptions = SortField.LONG; fieldName += Constants.Documents.Indexing.Fields.RangeFieldSuffixLong; break; case OrderByFieldType.Double: sortOptions = SortField.DOUBLE; fieldName += Constants.Documents.Indexing.Fields.RangeFieldSuffixDouble; break; } sortArray[sortIndex++] = new SortField(fieldName, sortOptions, field.Ascending == false); } sort = new Sort(sortArray); return(new ReturnSort(sortArray)); }
public static Sort GetSort(this IndexQuery self, IndexDefinition indexDefinition, AbstractViewGenerator viewGenerator) { var spatialQuery = self as SpatialIndexQuery; var sortedFields = self.SortedFields; if (sortedFields == null || sortedFields.Length <= 0) { if (spatialQuery == null || string.IsNullOrEmpty(self.Query) == false) { return(null); } sortedFields = new[] { new SortedField(Constants.DistanceFieldName), }; } return(new Sort(sortedFields .Select(sortedField => { if (sortedField.Field == Constants.TemporaryScoreValue) { return SortField.FIELD_SCORE; } if (sortedField.Field.StartsWith(Constants.AlphaNumericFieldName)) { var customField = SortFieldHelper.CustomField(sortedField.Field); if (string.IsNullOrEmpty(customField.Name)) { throw new InvalidOperationException("Alphanumeric sort: cannot figure out what field to sort on!"); } var anSort = new AlphaNumericComparatorSource(); return new SortField(customField.Name, anSort, sortedField.Descending); } if (sortedField.Field.StartsWith(Constants.RandomFieldName)) { var customField = SortFieldHelper.CustomField(sortedField.Field); if (string.IsNullOrEmpty(customField.Name)) // truly random { return new RandomSortField(Guid.NewGuid().ToString()); } return new RandomSortField(customField.Name); } if (sortedField.Field.StartsWith(Constants.CustomSortFieldName)) { var customField = SortFieldHelper.CustomField(sortedField.Field); if (string.IsNullOrEmpty(customField.Name)) { throw new InvalidOperationException("Custom sort: cannot figure out what field to sort on!"); } //backward compatibility for old clients var isDescending = sortedField.Descending || customField.Type[customField.Type.Length - 1] == '-'; return new CustomSortField(customField.Name, self, isDescending); } if (sortedField.Field.StartsWith(Constants.DistanceFieldName)) { SpatialField spatialField = null; Shape shape; if (sortedField.Field.Length == Constants.DistanceFieldName.Length) { if (spatialQuery == null) { throw new InvalidOperationException("Illegal Spatial Sort Parameter: Blank Spatial sort cannot be used without a spatial query"); } spatialField = viewGenerator.GetSpatialField(spatialQuery.SpatialFieldName); shape = spatialField.ReadShape(spatialQuery.QueryShape); } else { var sortParams = sortedField.Field.Split(';'); double lat, lng; if (sortParams.Length < 3 || !double.TryParse(sortParams[1], out lat) || !double.TryParse(sortParams[2], out lng)) { throw new InvalidOperationException("Illegal Spatial Sort Parameter"); } string spatialFieldName; if (sortParams.Length >= 4) { spatialFieldName = sortParams[3]; } else { if (spatialQuery == null) { spatialFieldName = Constants.DefaultSpatialFieldName; } else { spatialFieldName = spatialQuery.SpatialFieldName; } } spatialField = viewGenerator.GetSpatialField(spatialFieldName); shape = new PointImpl(lng, lat, spatialField.GetContext()); } var dsort = new SpatialDistanceFieldComparatorSource(spatialField, shape.GetCenter()); return new SortField(sortedField.Field, dsort, sortedField.Descending); } var sortOptions = GetSortOption(indexDefinition, sortedField.Field, self); if (sortOptions == null || sortOptions == SortOptions.None) { return new SortField(sortedField.Field, CultureInfo.InvariantCulture, sortedField.Descending); } if (sortOptions.Value == SortOptions.Short) { sortOptions = SortOptions.Int; } return new SortField(sortedField.Field, (int)sortOptions.Value, sortedField.Descending); }) .ToArray())); }