Example #1
0
        /// <summary>
        /// Detects numeric range terms and expands range expressions accordingly
        /// </summary>
        /// <param name="field"></param>
        /// <param name="lower"></param>
        /// <param name="upper"></param>
        /// <param name="inclusive"></param>
        /// <returns></returns>
        protected override Query GetRangeQuery(string field, string lower, string upper, bool inclusive)
        {
            if (lower == "NULL" || lower == "*")
            {
                lower = null;
            }
            if (upper == "NULL" || upper == "*")
            {
                upper = null;
            }

            if ((lower == null || !NumericRangeValue.IsMatch(lower)) && (upper == null || !NumericRangeValue.IsMatch(upper)))
            {
                return(NewRangeQuery(field, lower, upper, inclusive));
            }

            var from = NumberUtil.StringToNumber(lower);
            var to   = NumberUtil.StringToNumber(upper);

            TypeCode numericType;

            if (from != null)
            {
                numericType = Type.GetTypeCode(from.GetType());
            }
            else if (to != null)
            {
                numericType = Type.GetTypeCode(to.GetType());
            }
            else
            {
                numericType = TypeCode.Empty;
            }

            switch (numericType)
            {
            case TypeCode.Int32:
            {
                return(NumericRangeQuery.NewIntRange(field, (int)(from ?? Int32.MinValue), (int)(to ?? Int32.MaxValue), inclusive, inclusive));
            }

            case TypeCode.Int64:
            {
                return(NumericRangeQuery.NewLongRange(field, (long)(from ?? Int64.MinValue), (long)(to ?? Int64.MaxValue), inclusive, inclusive));
            }

            case TypeCode.Double:
            {
                return(NumericRangeQuery.NewDoubleRange(field, (double)(from ?? Double.MinValue), (double)(to ?? Double.MaxValue), inclusive, inclusive));
            }

            case TypeCode.Single:
            {
                return(NumericRangeQuery.NewFloatRange(field, (float)(from ?? Single.MinValue), (float)(to ?? Single.MaxValue), inclusive, inclusive));
            }

            default:
            {
                return(NewRangeQuery(field, lower, upper, inclusive));
            }
            }
        }
        /// <summary>
        /// This method generate the fields for indexing documents in lucene from the values.
        /// Given a name and a value, it has the following behavior:
        /// * If the value is null, create a single field with the supplied name with the unanalyzed value 'NULL_VALUE'
        /// * If the value is string or was set to not analyzed, create a single field with the supplied name
        /// * If the value is date, create a single field with millisecond precision with the supplied name
        /// * If the value is numeric (int, long, double, decimal, or float) will create two fields:
        ///		1. with the supplied name, containing the numeric value as an unanalyzed string - useful for direct queries
        ///		2. with the name: name +'_Range', containing the numeric value in a form that allows range queries
        /// </summary>
        private static IEnumerable <AbstractField> Createfields(string name, object value, IndexDefinition indexDefinition, Field.Store defaultStorage)
        {
            if (value == null)
            {
                yield return(new Field(name, "NULL_VALUE", indexDefinition.GetStorage(name, defaultStorage),
                                       Field.Index.NOT_ANALYZED));

                yield break;
            }

            if (indexDefinition.GetIndex(name, Field.Index.ANALYZED) == Field.Index.NOT_ANALYZED || value is string)
            {
                yield return(new Field(name, value.ToString(), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.ANALYZED)));

                yield break;
            }

            if (value is DateTime)
            {
                yield return(new Field(name, DateTools.DateToString((DateTime)value, DateTools.Resolution.MILLISECOND),
                                       indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            else if (value is IConvertible)            // we need this to store numbers in invariant format, so JSON could read them
            {
                var convert = ((IConvertible)value);
                yield return(new Field(name, convert.ToString(CultureInfo.InvariantCulture), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, GetDefaultIndexOption(value))));
            }
            else
            {
                yield return(new Field(name + "_ConvertToJson", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));

                yield return(new Field(name, JToken.FromObject(value).ToString(), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, GetDefaultIndexOption(value))));
            }


            if (value is int)
            {
                yield return(new Field(name + "_Range", NumberUtil.NumberToString((int)value), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            if (value is long)
            {
                yield return(new Field(name + "_Range", NumberUtil.NumberToString((long)value), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            if (value is decimal)
            {
                yield return(new Field(name + "_Range", NumberUtil.NumberToString((double)(decimal)value), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            if (value is float)
            {
                yield return(new Field(name + "_Range", NumberUtil.NumberToString((float)value), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            if (value is double)
            {
                yield return(new Field(name + "_Range", NumberUtil.NumberToString((double)value), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
        }