示例#1
0
        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()));
        }
示例#2
0
        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()));
        }
示例#3
0
        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));
        }
示例#4
0
        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()));
        }