/* * 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 NumericTokenStream = Lucene.Net.Analysis.NumericTokenStream; using TokenStream = Lucene.Net.Analysis.TokenStream; using NumericUtils = Lucene.Net.Util.NumericUtils; using FieldCache = Lucene.Net.Search.FieldCache; using NumericRangeFilter = Lucene.Net.Search.NumericRangeFilter; using NumericRangeQuery = Lucene.Net.Search.NumericRangeQuery; using SortField = Lucene.Net.Search.SortField; namespace Lucene.Net.Documents { // javadocs ///

This class provides a {@link Field} 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 {@link Document} 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 java 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 /// {@link java.util.Date} can be translated into a long /// value using the {@link java.util.Date#getTime} method. If you /// don't need millisecond precision, you can quantize the /// value, either by dividing the result of /// {@link 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 {@link NumericRangeQuery} or {@link /// NumericRangeFilter}. To sort according to a /// NumericField, use the normal numeric sort types, eg /// {@link SortField#INT} (note that {@link SortField#AUTO} /// will not work with these fields). NumericField values /// can also be loaded directly from {@link FieldCache}.

/// ///

By default, a NumericField's value is not stored but /// is indexed for range filtering and sorting. You can use /// the {@link #NumericField(String,Field.Store,boolean)} /// 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 {@link /// #NumericField(String,int,Field.Store,boolean)} if you'd /// like to change the value. Note that you must also /// specify a congruent value when creating {@link /// NumericRangeQuery} or {@link NumericRangeFilter}. /// For low cardinality fields larger precision steps are good. /// If the cardinality is < 100, it is fair /// to use {@link Integer#MAX_VALUE}, which produces one /// term per value. /// ///

For more information on the internals of numeric trie /// indexing, including the precisionStep /// configuration, see {@link NumericRangeQuery}. The format of /// indexed values is described in {@link NumericUtils}. /// ///

If you only need to sort by numeric value, and never /// run range querying/filtering, you can index using a /// precisionStep of {@link Integer#MAX_VALUE}. /// This will minimize disk space consumed.

/// ///

More advanced users can instead use {@link /// NumericTokenStream} 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 /// {@link Document} instance after search, you will get a /// conventional {@link Fieldable} instance where the numeric /// values are returned as {@link String}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 NumericTokenStream tokenStream; /// Creates a field for numeric values using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (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 /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (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 {@link NumericTokenStream} /// 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 {@link NumericTokenStream} /// 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) { SetOmitTermFreqAndPositions(true); tokenStream = new NumericTokenStream(precisionStep); } /// Returns a {@link NumericTokenStream} for indexing the numeric value. public override TokenStream TokenStreamValue() { return IsIndexed()?tokenStream:null; } /// Returns always null for numeric fields public override byte[] BinaryValue() { return null; } /// Returns always null for numeric fields public override byte[] GetBinaryValue(byte[] result) { return null; } /// Returns always null for numeric fields public override System.IO.TextReader ReaderValue() { return null; } /// Returns the numeric value as a string (how it is stored, when {@link Field.Store#YES} is chosen). public override System.String StringValue() { return (fieldsData == null)?null:fieldsData.ToString(); } /// Returns the current numeric value as a subclass of {@link Number}, null if not yet initialized. public System.ValueType GetNumericValue() { 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 = (long) 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 = (System.Int32) 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 = (double) 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 = (float) value_Renamed; return this; } } }