/* * 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; } } }