/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using Lucene.Net.Analysis.Tokenattributes; using Lucene.Net.Search; using AttributeSource = Lucene.Net.Util.AttributeSource; using NumericUtils = Lucene.Net.Util.NumericUtils; using NumericField = Lucene.Net.Documents.NumericField; // javadocs namespace Lucene.Net.Analysis { /// Expert: This class provides a /// for indexing numeric values that can be used by /// or . /// ///

Note that for simple usage, is /// recommended. disables norms and /// term freqs, as they are not usually needed during /// searching. If you need to change these settings, you /// should use this class. /// ///

See for capabilities of fields /// indexed numerically.

/// ///

Here's an example usage, for an int field: /// /// /// Field field = new Field(name, new NumericTokenStream(precisionStep).setIntValue(value)); /// field.setOmitNorms(true); /// field.setOmitTermFreqAndPositions(true); /// document.add(field); /// /// ///

For optimal performance, re-use the TokenStream and Field instance /// for more than one document: /// /// /// NumericTokenStream stream = new NumericTokenStream(precisionStep); /// Field field = new Field(name, stream); /// field.setOmitNorms(true); /// field.setOmitTermFreqAndPositions(true); /// Document document = new Document(); /// document.add(field); /// /// for(all documents) { /// stream.setIntValue(value) /// writer.addDocument(document); /// } /// /// ///

This stream is not intended to be used in analyzers; /// it's more for iterating the different precisions during /// indexing a specific numeric value.

/// ///

NOTE: as token streams are only consumed once /// the document is added to the index, if you index more /// than one numeric field, use a separate NumericTokenStream /// instance for each.

/// ///

See for more details on the /// precisionStep /// parameter as well as how numeric fields work under the hood.

/// ///

NOTE: This API is experimental and /// might change in incompatible ways in the next release. /// Since 2.9 ///

public sealed class NumericTokenStream : TokenStream { private void InitBlock() { termAtt = AddAttribute(); typeAtt = AddAttribute(); posIncrAtt = AddAttribute(); } /// The full precision token gets this token type assigned. public const System.String TOKEN_TYPE_FULL_PREC = "fullPrecNumeric"; /// The lower precision tokens gets this token type assigned. public const System.String TOKEN_TYPE_LOWER_PREC = "lowerPrecNumeric"; /// Creates a token stream for numeric values using the default precisionStep /// (4). The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream():this(NumericUtils.PRECISION_STEP_DEFAULT) { } /// Creates a token stream for numeric values with the specified /// precisionStep. The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream(int precisionStep):base() { InitBlock(); this.precisionStep = precisionStep; if (precisionStep < 1) throw new System.ArgumentException("precisionStep must be >=1"); } /// Expert: Creates a token stream for numeric values with the specified /// precisionStep using the given . /// The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream(AttributeSource source, int precisionStep):base(source) { InitBlock(); this.precisionStep = precisionStep; if (precisionStep < 1) throw new System.ArgumentException("precisionStep must be >=1"); } /// Expert: Creates a token stream for numeric values with the specified /// precisionStep using the given /// . /// The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream(AttributeFactory factory, int precisionStep):base(factory) { InitBlock(); this.precisionStep = precisionStep; if (precisionStep < 1) throw new System.ArgumentException("precisionStep must be >=1"); } /// Initializes the token stream with the supplied long value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetLongValue(value)) /// public NumericTokenStream SetLongValue(long value_Renamed) { this.value_Renamed = value_Renamed; valSize = 64; shift = 0; return this; } /// Initializes the token stream with the supplied int value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetIntValue(value)) /// public NumericTokenStream SetIntValue(int value_Renamed) { this.value_Renamed = (long) value_Renamed; valSize = 32; shift = 0; return this; } /// Initializes the token stream with the supplied double value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetDoubleValue(value)) /// public NumericTokenStream SetDoubleValue(double value_Renamed) { this.value_Renamed = NumericUtils.DoubleToSortableLong(value_Renamed); valSize = 64; shift = 0; return this; } /// Initializes the token stream with the supplied float value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetFloatValue(value)) /// public NumericTokenStream SetFloatValue(float value_Renamed) { this.value_Renamed = (long) NumericUtils.FloatToSortableInt(value_Renamed); valSize = 32; shift = 0; return this; } // @Override public override void Reset() { if (valSize == 0) throw new System.SystemException("call set???Value() before usage"); shift = 0; } protected override void Dispose(bool disposing) { // Do nothing. } // @Override public override bool IncrementToken() { if (valSize == 0) throw new System.SystemException("call set???Value() before usage"); if (shift >= valSize) return false; ClearAttributes(); char[] buffer; switch (valSize) { case 64: buffer = termAtt.ResizeTermBuffer(NumericUtils.BUF_SIZE_LONG); termAtt.SetTermLength(NumericUtils.LongToPrefixCoded(value_Renamed, shift, buffer)); break; case 32: buffer = termAtt.ResizeTermBuffer(NumericUtils.BUF_SIZE_INT); termAtt.SetTermLength(NumericUtils.IntToPrefixCoded((int) value_Renamed, shift, buffer)); break; default: // should not happen throw new System.ArgumentException("valSize must be 32 or 64"); } typeAtt.Type = (shift == 0)?TOKEN_TYPE_FULL_PREC:TOKEN_TYPE_LOWER_PREC; posIncrAtt.PositionIncrement = (shift == 0)?1:0; shift += precisionStep; return true; } // @Override public override System.String ToString() { System.Text.StringBuilder sb = new System.Text.StringBuilder("(numeric,valSize=").Append(valSize); sb.Append(",precisionStep=").Append(precisionStep).Append(')'); return sb.ToString(); } // members private ITermAttribute termAtt; private ITypeAttribute typeAtt; private IPositionIncrementAttribute posIncrAtt; private int shift = 0, valSize = 0; // valSize==0 means not initialized private readonly int precisionStep; private long value_Renamed = 0L; } }