I adapted Jeremies answer for C# and Lucene.Net 3.0.3.
I also needed type double instead of int.
This is my code:
using System.Globalization;
using Lucene.Net.Analysis;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Util;
using Version = Lucene.Net.Util.Version;
namespace SearchServer.SearchEngine
{
internal class SearchQueryParser : QueryParser
{
public SearchQueryParser(Analyzer analyzer)
: base(Version.LUCENE_30, null, analyzer)
{
}
private const NumberStyles DblNumberStyles = NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint;
protected override Query NewRangeQuery(string field, string part1, string part2, bool inclusive)
{
if (field == "p")
{
double part1Dbl;
if (!double.TryParse(part1, DblNumberStyles, CultureInfo.InvariantCulture, out part1Dbl))
throw new ParseException($"Error parsing value {part1} for field {field} as double.");
double part2Dbl;
if (!double.TryParse(part2, DblNumberStyles, CultureInfo.InvariantCulture, out part2Dbl))
throw new ParseException($"Error parsing value {part2} for field {field} as double.");
return NumericRangeQuery.NewDoubleRange(field, part1Dbl, part2Dbl, inclusive, inclusive);
}
return base.NewRangeQuery(field, part1, part2, inclusive);
}
protected override Query NewTermQuery(Term term)
{
if (term.Field == "p")
{
double dblParsed;
if (!double.TryParse(term.Text, DblNumberStyles, CultureInfo.InvariantCulture, out dblParsed))
throw new ParseException($"Error parsing value {term.Text} for field {term.Field} as double.");
return new TermQuery(new Term(term.Field, NumericUtils.DoubleToPrefixCoded(dblParsed)));
}
return base.NewTermQuery(term);
}
}
}
I improved my code to also allow queries like greater than and lower than when an asterisk is passed. E.g. p:[* TO 5]
...
double? part1Dbl = null;
double tmpDbl;
if (part1 != "*")
{
if (!double.TryParse(part1, DblNumberStyles, CultureInfo.InvariantCulture, out tmpDbl))
throw new ParseException($"Error parsing value {part1} for field {field} as double.");
part1Dbl = tmpDbl;
}
double? part2Dbl = null;
if (part2 != "*")
{
if (!double.TryParse(part2, DblNumberStyles, CultureInfo.InvariantCulture, out tmpDbl))
throw new ParseException($"Error parsing value {part2} for field {field} as double.");
part2Dbl = tmpDbl;
}
return NumericRangeQuery.NewDoubleRange(field, part1Dbl, part2Dbl, inclusive, inclusive);
...
specified query 'longField:bytes' contains a string based sub query which targets numeric encoded field(s)
. – Lennalennard