-
Notifications
You must be signed in to change notification settings - Fork 624
/
DoubleField.cs
188 lines (181 loc) · 8.66 KB
/
DoubleField.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
using Lucene.Net.Index;
using System;
namespace Lucene.Net.Documents
{
/*
* 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.
*/
/// <summary>
/// <para>
/// Field that indexes <see cref="double"/> values
/// for efficient range filtering and sorting. Here's an example usage:
///
/// <code>
/// document.Add(new DoubleField(name, 6.0, Field.Store.NO));
/// </code>
///
/// For optimal performance, re-use the <see cref="DoubleField"/> and
/// <see cref="Document"/> instance for more than one document:
///
/// <code>
/// DoubleField field = new DoubleField(name, 0.0, Field.Store.NO);
/// Document document = new Document();
/// document.Add(field);
///
/// for (all documents)
/// {
/// ...
/// field.SetDoubleValue(value)
/// writer.AddDocument(document);
/// ...
/// }
/// </code>
///
/// See also <seealso cref="Int32Field"/>, <seealso cref="Int64Field"/>,
/// <see cref="SingleField"/>.</para>
///
/// <para>To perform range querying or filtering against a
/// <see cref="DoubleField"/>, use <see cref="Search.NumericRangeQuery"/> or
/// <see cref="Search.NumericRangeFilter{T}"/>. To sort according to a
/// <see cref="DoubleField"/>, use the normal numeric sort types, eg
/// <see cref="Lucene.Net.Search.SortFieldType.DOUBLE"/>. <see cref="DoubleField"/>
/// values can also be loaded directly from <see cref="Search.IFieldCache"/>.</para>
///
/// <para>You may add the same field name as an <see cref="DoubleField"/> 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 <see cref="DoubleField"/>.</para>
///
/// <para>A <see cref="DoubleField"/> 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. </para>
///
/// <para>Within Lucene, each numeric value is indexed as a
/// <em>trie</em> 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
/// <c>precisionStep</c>, measured in bits. Smaller
/// <c>precisionStep</c> 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
/// create a custom <see cref="FieldType"/> and invoke the
/// <see cref="FieldType.NumericPrecisionStep"/> setter if you'd
/// like to change the value. Note that you must also
/// specify a congruent value when creating
/// <see cref="Search.NumericRangeQuery{T}"/> or <see cref="Search.NumericRangeFilter{T}"/>.
/// For low cardinality fields larger precision steps are good.
/// If the cardinality is < 100, it is fair
/// to use <see cref="int.MaxValue"/>, which produces one
/// term per value.</para>
///
/// <para>For more information on the internals of numeric trie
/// indexing, including the <see cref="Search.NumericRangeQuery{T}.PrecisionStep"/> (<a
/// href="../search/NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>)
/// configuration, see <see cref="Search.NumericRangeQuery{T}"/>. The format of
/// indexed values is described in <see cref="Util.NumericUtils"/>.</para>
///
/// <para>If you only need to sort by numeric value, and never
/// run range querying/filtering, you can index using a
/// <c>precisionStep</c> of <see cref="int.MaxValue"/>.
/// this will minimize disk space consumed. </para>
///
/// <para>More advanced users can instead use
/// <see cref="Analysis.NumericTokenStream"/> directly, when indexing numbers. This
/// class is a wrapper around this token stream type for
/// easier, more intuitive usage.</para>
///
/// @since 2.9
/// </summary>
public sealed class DoubleField : Field
{
/// <summary>
/// Type for a <see cref="DoubleField"/> that is not stored:
/// normalization factors, frequencies, and positions are omitted.
/// </summary>
public static readonly FieldType TYPE_NOT_STORED = LoadTypeNotStored();
private static FieldType LoadTypeNotStored() // LUCENENET: Avoid static constructors (see https://github.com/apache/lucenenet/pull/224#issuecomment-469284006)
{
var typeNotStored = new FieldType
{
IsIndexed = true,
IsTokenized = true,
OmitNorms = true,
IndexOptions = IndexOptions.DOCS_ONLY,
NumericType = Documents.NumericType.DOUBLE
};
typeNotStored.Freeze();
return typeNotStored;
}
/// <summary>
/// Type for a stored <see cref="DoubleField"/>:
/// normalization factors, frequencies, and positions are omitted.
/// </summary>
public static readonly FieldType TYPE_STORED = LoadTypeStored();
private static FieldType LoadTypeStored() // LUCENENET: Avoid static constructors (see https://github.com/apache/lucenenet/pull/224#issuecomment-469284006)
{
var typeStored = new FieldType
{
IsIndexed = true,
IsTokenized = true,
OmitNorms = true,
IndexOptions = IndexOptions.DOCS_ONLY,
NumericType = Documents.NumericType.DOUBLE,
IsStored = true
};
typeStored.Freeze();
return typeStored;
}
/// <summary>
/// Creates a stored or un-stored <see cref="DoubleField"/> with the provided value
/// and default <c>precisionStep</c>
/// <see cref="Util.NumericUtils.PRECISION_STEP_DEFAULT"/> (4).
/// </summary>
/// <param name="name"> field name </param>
/// <param name="value"> 64-bit <see cref="double"/> value </param>
/// <param name="stored"> <see cref="Field.Store.YES"/> if the content should also be stored </param>
/// <exception cref="ArgumentNullException"> if the field name is <c>null</c>. </exception>
public DoubleField(string name, double value, Store stored)
: base(name, stored == Store.YES ? TYPE_STORED : TYPE_NOT_STORED)
{
FieldsData = new Double(value);
}
/// <summary>
/// Expert: allows you to customize the <see cref="FieldType"/>.
/// </summary>
/// <param name="name"> field name </param>
/// <param name="value"> 64-bit double value </param>
/// <param name="type"> customized field type: must have <see cref="FieldType.NumericType"/>
/// of <see cref="NumericType.DOUBLE"/>. </param>
/// <exception cref="ArgumentNullException"> if the field name or type is <c>null</c>, or
/// if the field type does not have a <see cref="NumericType.DOUBLE"/> <see cref="FieldType.NumericType"/> </exception>
public DoubleField(string name, double value, FieldType type)
: base(name, type)
{
if (type.NumericType != Documents.NumericType.DOUBLE)
{
throw new ArgumentException("type.NumericType must be NumericType.DOUBLE but got " + type.NumericType);
}
FieldsData = new Double(value);
}
}
}