예제 #1
0
        private static ParsedRange ParseRange(string field, string range)
        {
            var parts = range.Split(new[] { " TO " }, 2, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length != 2)
            {
                throw new ArgumentException("Could not understand range query: " + range);
            }

            var trimmedLow  = parts[0].Trim();
            var trimmedHigh = parts[1].Trim();
            var parsedRange = new ParsedRange
            {
                Field         = field,
                RangeText     = range,
                LowInclusive  = IsInclusive(trimmedLow[0]),
                HighInclusive = IsInclusive(trimmedHigh[trimmedHigh.Length - 1]),
                LowValue      = trimmedLow.Substring(1),
                HighValue     = trimmedHigh.Substring(0, trimmedHigh.Length - 1)
            };

            parsedRange.LowValue  = ConvertFieldValue(field, parsedRange.LowValue);
            parsedRange.HighValue = ConvertFieldValue(field, parsedRange.HighValue);

            parsedRange.LowValue  = UnescapeValueIfNecessary(parsedRange.LowValue);
            parsedRange.HighValue = UnescapeValueIfNecessary(parsedRange.HighValue);

            return(parsedRange);
        }
예제 #2
0
        private static ParsedRange ParseRange(string field, string range)
        {
            var parts = range.Split(new[] { " TO " }, 2, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length != 2)
            {
                throw new ArgumentException("Could not understand range query: " + range);
            }

            var trimmedLow  = parts[0].Trim();
            var trimmedHigh = parts[1].Trim();
            var parsedRange = new ParsedRange
            {
                Field         = field,
                RangeText     = range,
                LowInclusive  = IsInclusive(trimmedLow.First()),
                HighInclusive = IsInclusive(trimmedHigh.Last()),
                LowValue      = trimmedLow.Substring(1),
                HighValue     = trimmedHigh.Substring(0, trimmedHigh.Length - 1)
            };

            if (RangeQueryParser.NumericRangeValue.IsMatch(parsedRange.LowValue))
            {
                parsedRange.LowValue = NumericStringToSortableNumeric(parsedRange.LowValue);
            }

            if (RangeQueryParser.NumericRangeValue.IsMatch(parsedRange.HighValue))
            {
                parsedRange.HighValue = NumericStringToSortableNumeric(parsedRange.HighValue);
            }


            if (parsedRange.LowValue == "NULL" || parsedRange.LowValue == "*")
            {
                parsedRange.LowValue = null;
            }
            if (parsedRange.HighValue == "NULL" || parsedRange.HighValue == "*")
            {
                parsedRange.HighValue = null;
            }

            parsedRange.LowValue  = UnescapeValueIfNecessary(parsedRange.LowValue);
            parsedRange.HighValue = UnescapeValueIfNecessary(parsedRange.HighValue);

            return(parsedRange);
        }
예제 #3
0
		private static ParsedRange ParseRange(string field, string range)
		{
			var parts = range.Split(new[] { " TO " }, 2, StringSplitOptions.RemoveEmptyEntries);

			if (parts.Length != 2)
				throw new ArgumentException("Could not understand range query: " + range);

			var trimmedLow = parts[0].Trim();
			var trimmedHigh = parts[1].Trim();
			var parsedRange = new ParsedRange
			{
				Field = field,
				RangeText = range,
				LowInclusive = IsInclusive(trimmedLow.First()),
				HighInclusive = IsInclusive(trimmedHigh.Last()),
				LowValue = trimmedLow.Substring(1),
				HighValue = trimmedHigh.Substring(0, trimmedHigh.Length - 1)
			};

			if (RangeQueryParser.NumericRangeValue.IsMatch(parsedRange.LowValue))
			{
				parsedRange.LowValue = NumericStringToSortableNumeric(parsedRange.LowValue);
			}

			if (RangeQueryParser.NumericRangeValue.IsMatch(parsedRange.HighValue))
			{
				parsedRange.HighValue = NumericStringToSortableNumeric(parsedRange.HighValue);
			}


			if (parsedRange.LowValue == "NULL" || parsedRange.LowValue == "*")
				parsedRange.LowValue = null;
			if (parsedRange.HighValue == "NULL" || parsedRange.HighValue == "*")
				parsedRange.HighValue = null;



			return parsedRange;
		}
예제 #4
0
 private void ApplyFacetValueHit(FacetValue facetValue, Facet value, int docId, ParsedRange parsedRange)
 {
     facetValue.Hits++;
     if (value.Aggregation == FacetAggregation.Count || value.Aggregation == FacetAggregation.None)
     {
         return;
     }
     FacetValueState set;
     if (matches.TryGetValue(facetValue, out set) == false)
     {
         matches[facetValue] = set = new FacetValueState
         {
             Docs = new HashSet<int>(),
             Facet = value,
             Range = parsedRange
         };
     }
     set.Docs.Add(docId);
 }
예제 #5
0
            private void ApplyFacetValueHit(FacetValue facetValue, Facet value, int docId, ParsedRange parsedRange, IndexReader indexReader)
            {
                facetValue.Hits++;
                if (
                    IndexQuery.IsDistinct == false &&
                    (value.Aggregation == FacetAggregation.Count || value.Aggregation == FacetAggregation.None)
                    )
                {
                    return;
                }
                FacetValueState set;

                if (matches.TryGetValue(facetValue, out set) == false)
                {
                    matches[facetValue] = set = new FacetValueState
                    {
                        Docs  = new HashSet <int>(),
                        Facet = value,
                        Range = parsedRange
                    };
                }
                if (IndexQuery.IsDistinct)
                {
                    if (IndexQuery.FieldsToFetch.Length == 0)
                    {
                        throw new InvalidOperationException("Cannot process distinct facet query without specifying which fields to distinct upon.");
                    }

                    if (set.AlreadySeen == null)
                    {
                        set.AlreadySeen = new HashSet <StringCollectionValue>();
                    }

                    var document = indexReader.Document(docId);
                    var fields   = new List <string>();
                    foreach (var fieldName in IndexQuery.FieldsToFetch)
                    {
                        foreach (var field in document.GetFields(fieldName))
                        {
                            if (field.StringValue == null)
                            {
                                continue;
                            }
                            fields.Add(field.StringValue);
                        }
                    }
                    if (fields.Count == 0)
                    {
                        throw new InvalidOperationException("Cannot apply distinct facet on [" + string.Join(", ", IndexQuery.FieldsToFetch) +
                                                            "], did you forget to store them in the index? ");
                    }

                    if (set.AlreadySeen.Add(new StringCollectionValue(fields)) == false)
                    {
                        facetValue.Hits--;            // already seen, cancel this
                        return;
                    }
                }
                set.Docs.Add(docId);
            }
예제 #6
0
            private void ApplyFacetValueHit(FacetValue facetValue, Facet value, int docId, ParsedRange parsedRange)
            {
                facetValue.Hits++;
                if (value.Aggregation == FacetAggregation.Count || value.Aggregation == FacetAggregation.None)
                {
                    return;
                }
                FacetValueState set;

                if (matches.TryGetValue(facetValue, out set) == false)
                {
                    matches[facetValue] = set = new FacetValueState
                    {
                        Docs  = new HashSet <int>(),
                        Facet = value,
                        Range = parsedRange
                    };
                }
                set.Docs.Add(docId);
            }
예제 #7
0
            private void ApplyFacetValueHit(FacetValue facetValue, Facet value, int docId, ParsedRange parsedRange, IndexReader indexReader)
            {
                facetValue.Hits++;
                if (
					IndexQuery.IsDistinct == false &&
					(value.Aggregation == FacetAggregation.Count || value.Aggregation == FacetAggregation.None)
				   )
                {
                    return;
                }
                FacetValueState set;
                if (matches.TryGetValue(facetValue, out set) == false)
                {
                    matches[facetValue] = set = new FacetValueState
                    {
                        Docs = new HashSet<int>(),
                        Facet = value,
                        Range = parsedRange
                    };
                }
	            if (IndexQuery.IsDistinct)
	            {
					if(IndexQuery.FieldsToFetch.Length == 0)
						throw new InvalidOperationException("Cannot process distinct facet query without specifying which fields to distinct upon.");

		            if (set.AlreadySeen == null)
			            set.AlreadySeen = new HashSet<StringCollectionValue>();

		            var document = indexReader.Document(docId);
		            var fields = new List<string>();
					foreach (var fieldName in IndexQuery.FieldsToFetch)
		            {
						foreach (var field in document.GetFields(fieldName))
						{
							if (field.StringValue == null)
								continue;
				            fields.Add(field.StringValue);
			            }
		            }
		            if (fields.Count == 0)
			            throw new InvalidOperationException("Cannot apply distinct facet on [" + string.Join(", ", IndexQuery.FieldsToFetch) +
							"], did you forget to store them in the index? ");

		            if (set.AlreadySeen.Add(new StringCollectionValue(fields)) == false)
		            {
			            facetValue.Hits--;// already seen, cancel this
			            return;
		            }
	            }
                set.Docs.Add(docId);
            }
예제 #8
0
        private static ParsedRange ParseRange(QueryExpression expression, FacetQuery query, out RangeType type)
        {
            if (expression is BetweenExpression bee)
            {
                var hValue = ConvertFieldValue(bee.Max.Token.Value, bee.Max.Value, query.Query.QueryParameters);
                var lValue = ConvertFieldValue(bee.Min.Token.Value, bee.Min.Value, query.Query.QueryParameters);

                var fieldName = ((FieldExpression)bee.Source).GetText(null);

                if (hValue.Type != lValue.Type)
                {
                    ThrowDifferentTypesOfRangeValues(query, hValue.Type, lValue.Type, fieldName);
                }

                type = hValue.Type;

                var range = new ParsedRange
                {
                    Field         = fieldName,
                    HighInclusive = true,
                    HighValue     = hValue.Value,
                    LowInclusive  = true,
                    LowValue      = lValue.Value,
                    RangeText     = expression.GetText(query.Query)
                };

                return(range);
            }

            if (expression is BinaryExpression be)
            {
                switch (be.Operator)
                {
                case OperatorType.LessThan:
                case OperatorType.GreaterThan:
                case OperatorType.LessThanEqual:
                case OperatorType.GreaterThanEqual:
                    var fieldName = ExtractFieldName(be, query);

                    var r          = (ValueExpression)be.Right;
                    var fieldValue = ConvertFieldValue(r.Token.Value, r.Value, query.Query.QueryParameters);

                    type = fieldValue.Type;

                    var range = new ParsedRange
                    {
                        Field     = fieldName,
                        RangeText = expression.GetText(query.Query)
                    };

                    if (be.Operator == OperatorType.LessThan || be.Operator == OperatorType.LessThanEqual)
                    {
                        range.HighValue     = fieldValue.Value;
                        range.HighInclusive = be.Operator == OperatorType.LessThanEqual;

                        return(range);
                    }

                    if (be.Operator == OperatorType.GreaterThan || be.Operator == OperatorType.GreaterThanEqual)
                    {
                        range.LowValue     = fieldValue.Value;
                        range.LowInclusive = be.Operator == OperatorType.GreaterThanEqual;

                        return(range);
                    }

                    return(range);

                case OperatorType.And:
                    var left  = ParseRange(be.Left, query, out var lType);
                    var right = ParseRange(be.Right, query, out var rType);

                    if (lType != rType)
                    {
                        ThrowDifferentTypesOfRangeValues(query, lType, rType, left.Field);
                    }

                    type = lType;

                    if (left.HighValue == null)
                    {
                        left.HighValue     = right.HighValue;
                        left.HighInclusive = right.HighInclusive;
                    }

                    if (left.LowValue == null)
                    {
                        left.LowValue     = right.LowValue;
                        left.LowInclusive = right.LowInclusive;
                    }

                    left.RangeText = $"{left.RangeText} and {right.RangeText}";
                    return(left);

                default:
                    ThrowUnsupportedRangeOperator(query, be.Operator);
                    break;
                }
            }

            ThrowUnsupportedRangeExpression(query, expression);
            type = RangeType.None;
            return(null);
        }