Port numeric query nodes
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/8b4f3d95 Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/8b4f3d95 Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/8b4f3d95 Branch: refs/heads/branch_4x Commit: 8b4f3d95b2b98506d165b71de931b6d16cf5864a Parents: c50db23 Author: Paul Irwin <[email protected]> Authored: Sun Oct 6 10:26:16 2013 -0400 Committer: Paul Irwin <[email protected]> Committed: Sun Oct 6 10:26:16 2013 -0400 ---------------------------------------------------------------------- .../QueryParsers/Contrib.QueryParsers.csproj | 3 + .../Flexible/Standard/Config/NumericConfig.cs | 63 ++++++++++ .../Flexible/Standard/Nodes/NumericQueryNode.cs | 84 +++++++++++++ .../Standard/Nodes/NumericRangeQueryNode.cs | 126 +++++++++++++++++++ 4 files changed, 276 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8b4f3d95/src/contrib/QueryParsers/Contrib.QueryParsers.csproj ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj index 195d08e..75be5c6 100644 --- a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj +++ b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj @@ -121,10 +121,13 @@ <Compile Include="Flexible\Standard\Builders\MatchNoDocsQueryNodeBuilder.cs" /> <Compile Include="Flexible\Standard\Builders\ModifierQueryNodeBuilder.cs" /> <Compile Include="Flexible\Standard\Builders\MultiPhraseQueryNodeBuilder.cs" /> + <Compile Include="Flexible\Standard\Config\NumericConfig.cs" /> <Compile Include="Flexible\Standard\ICommonQueryParserConfiguration.cs" /> <Compile Include="Flexible\Standard\Nodes\AbstractRangeQueryNode.cs" /> <Compile Include="Flexible\Standard\Nodes\BooleanModifierNode.cs" /> <Compile Include="Flexible\Standard\Nodes\MultiPhraseQueryNode.cs" /> + <Compile Include="Flexible\Standard\Nodes\NumericQueryNode.cs" /> + <Compile Include="Flexible\Standard\Nodes\NumericRangeQueryNode.cs" /> <Compile Include="Flexible\Standard\Parser\EscapeQuerySyntaxImpl.cs" /> <Compile Include="Flexible\Standard\Parser\ICharStream.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8b4f3d95/src/contrib/QueryParsers/Flexible/Standard/Config/NumericConfig.cs ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Flexible/Standard/Config/NumericConfig.cs b/src/contrib/QueryParsers/Flexible/Standard/Config/NumericConfig.cs new file mode 100644 index 0000000..be0c86c --- /dev/null +++ b/src/contrib/QueryParsers/Flexible/Standard/Config/NumericConfig.cs @@ -0,0 +1,63 @@ +using Lucene.Net.Documents; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lucene.Net.QueryParsers.Flexible.Standard.Config +{ + public class NumericConfig + { + private int precisionStep; + + private NumberFormatInfo format; + + private FieldType.NumericType type; + + public NumericConfig(int precisionStep, NumberFormatInfo format, FieldType.NumericType type) + { + PrecisionStep = precisionStep; + NumberFormat = format; + this.Type = type; + } + + public int PrecisionStep + { + get { return precisionStep; } + set { precisionStep = value; } + } + + public NumberFormatInfo NumberFormat + { + get { return format; } + set { format = value; } + } + + public FieldType.NumericType Type + { + get { return type; } + set { type = value; } + } + + public override bool Equals(object obj) + { + if (obj == this) return true; + + if (obj is NumericConfig) + { + NumericConfig other = (NumericConfig)obj; + + if (this.precisionStep == other.precisionStep + && this.type == other.type + && (this.format == other.format || (this.format.Equals(other.format)))) + { + return true; + } + } + + return false; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8b4f3d95/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericQueryNode.cs ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericQueryNode.cs b/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericQueryNode.cs new file mode 100644 index 0000000..dcbdf74 --- /dev/null +++ b/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericQueryNode.cs @@ -0,0 +1,84 @@ +using Lucene.Net.QueryParsers.Flexible.Core.Nodes; +using Lucene.Net.QueryParsers.Flexible.Core.Parser; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes +{ + public class NumericQueryNode<T> : QueryNode, IFieldValuePairQueryNode<T> + where T : struct + { + private NumberFormatInfo numberFormat; + + private string field; + + private T value; + + public NumericQueryNode(string field, T value, NumberFormatInfo numberFormat) + : base() + { + NumberFormat = numberFormat; + Field = field; + Value = value; + } + + public string Field + { + get + { + return this.field; + } + set + { + this.field = value; + } + } + + protected ICharSequence GetTermEscaped(IEscapeQuerySyntax escaper) + { + return escaper.Escape(new StringCharSequenceWrapper(Convert.ToString(this.value, this.numberFormat)), + CultureInfo.InvariantCulture, EscapeQuerySyntax.Type.NORMAL); + } + + public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser) + { + if (IsDefaultField(this.field)) + { + return GetTermEscaped(escapeSyntaxParser); + } + else + { + return new StringCharSequenceWrapper(this.field + ":" + GetTermEscaped(escapeSyntaxParser)); + } + } + + public NumberFormatInfo NumberFormat + { + get { return this.numberFormat; } + set { this.numberFormat = value; } + } + + public T Value + { + get + { + return this.value; + } + set + { + this.value = value; + } + } + + public override string ToString() + { + return "<numeric field='" + this.field + "' number='" + + Convert.ToString(this.value, this.numberFormat) + "'/>"; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8b4f3d95/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericRangeQueryNode.cs ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericRangeQueryNode.cs b/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericRangeQueryNode.cs new file mode 100644 index 0000000..a393030 --- /dev/null +++ b/src/contrib/QueryParsers/Flexible/Standard/Nodes/NumericRangeQueryNode.cs @@ -0,0 +1,126 @@ +using Lucene.Net.Documents; +using Lucene.Net.QueryParsers.Flexible.Core; +using Lucene.Net.QueryParsers.Flexible.Core.Messages; +using Lucene.Net.QueryParsers.Flexible.Messages; +using Lucene.Net.QueryParsers.Flexible.Standard.Config; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NumericType = Lucene.Net.Documents.FieldType.NumericType; + +namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes +{ + public class NumericRangeQueryNode<T> : AbstractRangeQueryNode<NumericQueryNode<T>> + where T : struct + { + public NumericConfig numericConfig; + + public NumericRangeQueryNode(NumericQueryNode<T> lower, NumericQueryNode<T> upper, + bool lowerInclusive, bool upperInclusive, NumericConfig numericConfig) + { + SetBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig); + } + + private static NumericType GetNumericDataType(T number) + { + if (number is long) + { + return NumericType.LONG; + } + else if (number is int) + { + return NumericType.INT; + } + else if (number is double) + { + return NumericType.DOUBLE; + } + else if (number is float) + { + return NumericType.FLOAT; + } + else + { + throw new QueryNodeException( + new Message( + QueryParserMessages.NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY, + number.GetType())); + } + } + + public void SetBounds(NumericQueryNode<T> lower, NumericQueryNode<T> upper, + bool lowerInclusive, bool upperInclusive, NumericConfig numericConfig) + { + + if (numericConfig == null) + { + throw new ArgumentException("numericConfig cannot be null!"); + } + + NumericType? lowerNumberType, upperNumberType; + + if (lower != null /* && lower.Value != null */) + { + lowerNumberType = GetNumericDataType(lower.Value); + } + else + { + lowerNumberType = null; + } + + if (upper != null /* && upper.Value != null */) + { + upperNumberType = GetNumericDataType(upper.Value); + } + else + { + upperNumberType = null; + } + + if (lowerNumberType != null + && !lowerNumberType.Equals(numericConfig.Type)) + { + throw new ArgumentException( + "lower value's type should be the same as numericConfig type: " + + lowerNumberType + " != " + numericConfig.Type); + } + + if (upperNumberType != null + && !upperNumberType.Equals(numericConfig.Type)) + { + throw new ArgumentException( + "upper value's type should be the same as numericConfig type: " + + upperNumberType + " != " + numericConfig.Type); + } + + base.SetBounds(lower, upper, lowerInclusive, upperInclusive); + this.numericConfig = numericConfig; + } + + public NumericConfig NumericConfig + { + get + { + return this.numericConfig; + } + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder("<numericRange lowerInclusive='"); + + sb.Append(IsLowerInclusive).Append("' upperInclusive='").Append( + IsUpperInclusive).Append( + "' precisionStep='" + numericConfig.PrecisionStep).Append( + "' type='" + numericConfig.Type).Append("'>\n"); + + sb.Append(LowerBound).Append('\n'); + sb.Append(UpperBound).Append('\n'); + sb.Append("</numericRange>"); + + return sb.ToString(); + } + } +}
