/*
* 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 System;
using System.IO;
using Lucene.Net.Search;
using NumericTokenStream = Lucene.Net.Analysis.NumericTokenStream;
using TokenStream = Lucene.Net.Analysis.TokenStream;
using NumericUtils = Lucene.Net.Util.NumericUtils;
using FieldCache = Lucene.Net.Search.FieldCache;
using SortField = Lucene.Net.Search.SortField;
namespace Lucene.Net.Documents
{
// javadocs
/// This class provides a that enables indexing
/// of numeric values for efficient range filtering and
/// sorting. Here's an example usage, adding an int value:
///
/// document.add(new NumericField(name).setIntValue(value));
///
///
/// For optimal performance, re-use the
/// NumericField and instance for more than
/// one document:
///
///
/// NumericField field = new NumericField(name);
/// Document document = new Document();
/// document.add(field);
///
/// for(all documents) {
/// ...
/// field.setIntValue(value)
/// writer.addDocument(document);
/// ...
/// }
///
///
/// The .Net native types int, long,
/// float and double are
/// directly supported. However, any value that can be
/// converted into these native types can also be indexed.
/// For example, date/time values represented by a
/// can be translated into a long
/// value using the java.util.Date.getTime method. If you
/// don't need millisecond precision, you can quantize the
/// value, either by dividing the result of
/// java.util.Date.getTime or using the separate getters
/// (for year, month, etc.) to construct an int or
/// long value.
///
/// To perform range querying or filtering against a
/// NumericField, use or
///. To sort according to a
/// NumericField, use the normal numeric sort types, eg
/// NumericField values
/// can also be loaded directly from .
///
/// By default, a NumericField's value is not stored but
/// is indexed for range filtering and sorting. You can use
/// the
/// constructor if you need to change these defaults.
///
/// You may add the same field name as a NumericField to
/// the same document more than once. Range querying and
/// filtering will be the logical OR of all values; so a range query
/// will hit all documents that have at least one value in
/// the range. However sort behavior is not defined. If you need to sort,
/// you should separately index a single-valued NumericField.
///
/// A NumericField will consume somewhat more disk space
/// in the index than an ordinary single-valued field.
/// However, for a typical index that includes substantial
/// textual content per document, this increase will likely
/// be in the noise.
///
/// Within Lucene, each numeric value is indexed as a
/// trie structure, where each term is logically
/// assigned to larger and larger pre-defined brackets (which
/// are simply lower-precision representations of the value).
/// The step size between each successive bracket is called the
/// precisionStep, measured in bits. Smaller
/// precisionStep values result in larger number
/// of brackets, which consumes more disk space in the index
/// but may result in faster range search performance. The
/// default value, 4, was selected for a reasonable tradeoff
/// of disk space consumption versus performance. You can
/// use the expert constructor
/// if you'd
/// like to change the value. Note that you must also
/// specify a congruent value when creating
/// or .
/// For low cardinality fields larger precision steps are good.
/// If the cardinality is < 100, it is fair
/// to use , which produces one
/// term per value.
///
/// For more information on the internals of numeric trie
/// indexing, including the precisionStep
/// configuration, see . The format of
/// indexed values is described in .
///
/// If you only need to sort by numeric value, and never
/// run range querying/filtering, you can index using a
/// precisionStep of .
/// This will minimize disk space consumed.
///
/// More advanced users can instead use
/// directly, when indexing numbers. This
/// class is a wrapper around this token stream type for
/// easier, more intuitive usage.
///
/// NOTE: This class is only used during
/// indexing. When retrieving the stored field value from a
/// instance after search, you will get a
/// conventional instance where the numeric
/// values are returned as s (according to
/// toString(value) of the used data type).
///
/// NOTE: This API is
/// experimental and might change in incompatible ways in the
/// next release.
///
///
/// 2.9
///
[Serializable]
public sealed class NumericField:AbstractField
{
new private readonly NumericTokenStream tokenStream;
/// Creates a field for numeric values using the default precisionStep
/// (4). The instance is not yet initialized with
/// a numeric value, before indexing a document containing this field,
/// set a value using the various set???Value() methods.
/// This constructor creates an indexed, but not stored field.
///
/// the field name
///
public NumericField(System.String name):this(name, NumericUtils.PRECISION_STEP_DEFAULT, Field.Store.NO, true)
{
}
/// Creates a field for numeric values using the default precisionStep
/// (4). The instance is not yet initialized with
/// a numeric value, before indexing a document containing this field,
/// set a value using the various set???Value() methods.
///
/// the field name
///
/// if the field should be stored in plain text form
/// (according to toString(value) of the used data type)
///
/// if the field should be indexed using
///
public NumericField(System.String name, Field.Store store, bool index):this(name, NumericUtils.PRECISION_STEP_DEFAULT, store, index)
{
}
/// Creates a field for numeric values with the specified
/// precisionStep. The instance is not yet initialized with
/// a numeric value, before indexing a document containing this field,
/// set a value using the various set???Value() methods.
/// This constructor creates an indexed, but not stored field.
///
/// the field name
///
/// the used precision step
///
public NumericField(System.String name, int precisionStep):this(name, precisionStep, Field.Store.NO, true)
{
}
/// Creates a field for numeric values with the specified
/// precisionStep. The instance is not yet initialized with
/// a numeric value, before indexing a document containing this field,
/// set a value using the various set???Value() methods.
///
/// the field name
///
/// the used precision step
///
/// if the field should be stored in plain text form
/// (according to toString(value) of the used data type)
///
/// if the field should be indexed using
///
public NumericField(System.String name, int precisionStep, Field.Store store, bool index):base(name, store, index?Field.Index.ANALYZED_NO_NORMS:Field.Index.NO, Field.TermVector.NO)
{
OmitTermFreqAndPositions = true;
tokenStream = new NumericTokenStream(precisionStep);
}
/// Returns a for indexing the numeric value.
public override TokenStream TokenStreamValue
{
get { return IsIndexed ? tokenStream : null; }
}
/// Returns always null for numeric fields
public override byte[] GetBinaryValue(byte[] result)
{
return null;
}
/// Returns always null for numeric fields
public override TextReader ReaderValue
{
get { return null; }
}
/// Returns the numeric value as a string (how it is stored, when is chosen).
public override string StringValue
{
get { return (fieldsData == null) ? null : fieldsData.ToString(); }
}
/// Returns the current numeric value as a subclass of , null if not yet initialized.
public ValueType NumericValue
{
get { return (System.ValueType) fieldsData; }
}
/// Initializes the field with the supplied long value.
/// the numeric value
///
/// this instance, because of this you can use it the following way:
/// document.add(new NumericField(name, precisionStep).SetLongValue(value))
///
public NumericField SetLongValue(long value_Renamed)
{
tokenStream.SetLongValue(value_Renamed);
fieldsData = value_Renamed;
return this;
}
/// Initializes the field with the supplied int value.
/// the numeric value
///
/// this instance, because of this you can use it the following way:
/// document.add(new NumericField(name, precisionStep).setIntValue(value))
///
public NumericField SetIntValue(int value_Renamed)
{
tokenStream.SetIntValue(value_Renamed);
fieldsData = value_Renamed;
return this;
}
/// Initializes the field with the supplied double value.
/// the numeric value
///
/// this instance, because of this you can use it the following way:
/// document.add(new NumericField(name, precisionStep).setDoubleValue(value))
///
public NumericField SetDoubleValue(double value_Renamed)
{
tokenStream.SetDoubleValue(value_Renamed);
fieldsData = value_Renamed;
return this;
}
/// Initializes the field with the supplied float value.
/// the numeric value
///
/// this instance, because of this you can use it the following way:
/// document.add(new NumericField(name, precisionStep).setFloatValue(value))
///
public NumericField SetFloatValue(float value_Renamed)
{
tokenStream.SetFloatValue(value_Renamed);
fieldsData = value_Renamed;
return this;
}
}
}