Skip to content

Commit 9b05acd

Browse files
authored
support for index and search with missing / empty values (#315)
search with missing empty values
1 parent 4b10eac commit 9b05acd

File tree

3 files changed

+203
-47
lines changed

3 files changed

+203
-47
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
namespace NRedisStack.Search.Literals;
22

3-
internal class AttributeOptions
3+
internal class FieldOptions
44
{
55
public const string SORTABLE = "SORTABLE";
66
public const string UNF = "UNF";
77
public const string NOSTEM = "NOSTEM";
88
public const string NOINDEX = "NOINDEX";
9+
public const string INDEXEMPTY = "INDEXEMPTY";
10+
public const string INDEXMISSING = "INDEXMISSING";
911

1012
//TODO: add all options
1113
}

src/NRedisStack/Search/Schema.cs

+74-46
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ public class TextField : Field
6262
public bool Unf { get; }
6363
public bool NoIndex { get; }
6464
public bool WithSuffixTrie { get; }
65+
public bool MissingIndex { get; }
66+
public bool EmptyIndex { get; }
6567

6668
public TextField(FieldName name, double weight = 1.0, bool noStem = false,
6769
string? phonetic = null, bool sortable = false, bool unf = false,
68-
bool noIndex = false, bool withSuffixTrie = false)
70+
bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
6971
: base(name, FieldType.Text)
7072
{
7173
Weight = weight;
@@ -79,12 +81,14 @@ public TextField(FieldName name, double weight = 1.0, bool noStem = false,
7981
Unf = unf;
8082
NoIndex = noIndex;
8183
WithSuffixTrie = withSuffixTrie;
84+
MissingIndex = missingIndex;
85+
EmptyIndex = emptyIndex;
8286
}
8387

8488
public TextField(string name, double weight = 1.0, bool noStem = false,
8589
string? phonetic = null, bool sortable = false, bool unf = false,
86-
bool noIndex = false, bool withSuffixTrie = false)
87-
: this(FieldName.Of(name), weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie) { }
90+
bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
91+
: this(FieldName.Of(name), weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie, missingIndex, emptyIndex) { }
8892

8993
internal override void AddFieldTypeArgs(List<object> args)
9094
{
@@ -93,8 +97,11 @@ internal override void AddFieldTypeArgs(List<object> args)
9397
AddPhonetic(args);
9498
AddWeight(args);
9599
if (WithSuffixTrie) args.Add(SearchArgs.WITHSUFFIXTRIE);
96-
if (Sortable) args.Add(AttributeOptions.SORTABLE);
100+
if (Sortable) args.Add(FieldOptions.SORTABLE);
97101
if (Unf) args.Add(SearchArgs.UNF);
102+
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
103+
if (EmptyIndex) args.Add(FieldOptions.INDEXEMPTY);
104+
98105
}
99106

100107
private void AddWeight(List<object> args)
@@ -124,10 +131,12 @@ public class TagField : Field
124131
public string Separator { get; }
125132
public bool CaseSensitive { get; }
126133
public bool WithSuffixTrie { get; }
134+
public bool MissingIndex { get; }
135+
public bool EmptyIndex { get; }
127136

128137
internal TagField(FieldName name, bool sortable = false, bool unf = false,
129138
bool noIndex = false, string separator = ",",
130-
bool caseSensitive = false, bool withSuffixTrie = false)
139+
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
131140
: base(name, FieldType.Tag)
132141
{
133142
Sortable = sortable;
@@ -136,12 +145,14 @@ internal TagField(FieldName name, bool sortable = false, bool unf = false,
136145
Separator = separator;
137146
CaseSensitive = caseSensitive;
138147
WithSuffixTrie = withSuffixTrie;
148+
EmptyIndex = emptyIndex;
149+
MissingIndex = missingIndex;
139150
}
140151

141152
internal TagField(string name, bool sortable = false, bool unf = false,
142153
bool noIndex = false, string separator = ",",
143-
bool caseSensitive = false, bool withSuffixTrie = false)
144-
: this(FieldName.Of(name), sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie) { }
154+
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
155+
: this(FieldName.Of(name), sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie, missingIndex, emptyIndex) { }
145156

146157
internal override void AddFieldTypeArgs(List<object> args)
147158
{
@@ -154,29 +165,35 @@ internal override void AddFieldTypeArgs(List<object> args)
154165
args.Add(Separator);
155166
}
156167
if (CaseSensitive) args.Add(SearchArgs.CASESENSITIVE);
157-
if (Sortable) args.Add(AttributeOptions.SORTABLE);
168+
if (Sortable) args.Add(FieldOptions.SORTABLE);
158169
if (Unf) args.Add(SearchArgs.UNF);
170+
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
171+
if (EmptyIndex) args.Add(FieldOptions.INDEXEMPTY);
159172
}
160173
}
161174

162175
public class GeoField : Field
163176
{
164177
public bool Sortable { get; }
165178
public bool NoIndex { get; }
166-
internal GeoField(FieldName name, bool sortable = false, bool noIndex = false)
179+
public bool MissingIndex { get; }
180+
181+
internal GeoField(FieldName name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
167182
: base(name, FieldType.Geo)
168183
{
169184
Sortable = sortable;
170185
NoIndex = noIndex;
186+
MissingIndex = missingIndex;
171187
}
172188

173-
internal GeoField(string name, bool sortable = false, bool noIndex = false)
174-
: this(FieldName.Of(name), sortable, noIndex) { }
189+
internal GeoField(string name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
190+
: this(FieldName.Of(name), sortable, noIndex, missingIndex) { }
175191

176192
internal override void AddFieldTypeArgs(List<object> args)
177193
{
178194
if (NoIndex) args.Add(SearchArgs.NOINDEX);
179-
if (Sortable) args.Add(AttributeOptions.SORTABLE);
195+
if (Sortable) args.Add(FieldOptions.SORTABLE);
196+
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
180197
}
181198

182199
}
@@ -196,40 +213,47 @@ public enum CoordinateSystem
196213
SPHERICAL
197214
}
198215
private CoordinateSystem system { get; }
216+
public bool MissingIndex { get; }
199217

200-
internal GeoShapeField(FieldName name, CoordinateSystem system)
218+
internal GeoShapeField(FieldName name, CoordinateSystem system, bool missingIndex = false)
201219
: base(name, FieldType.GeoShape)
202220
{
203221
this.system = system;
222+
MissingIndex = missingIndex;
204223
}
205224

206-
internal GeoShapeField(string name, CoordinateSystem system)
207-
: this(FieldName.Of(name), system) { }
225+
internal GeoShapeField(string name, CoordinateSystem system, bool missingIndex = false)
226+
: this(FieldName.Of(name), system, missingIndex) { }
208227

209228
internal override void AddFieldTypeArgs(List<object> args)
210229
{
211230
args.Add(system.ToString());
231+
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
212232
}
213233
}
214234

215235
public class NumericField : Field
216236
{
217237
public bool Sortable { get; }
218238
public bool NoIndex { get; }
219-
internal NumericField(FieldName name, bool sortable = false, bool noIndex = false)
239+
public bool MissingIndex { get; }
240+
241+
internal NumericField(FieldName name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
220242
: base(name, FieldType.Numeric)
221243
{
222244
Sortable = sortable;
223245
NoIndex = noIndex;
246+
MissingIndex = missingIndex;
224247
}
225248

226-
internal NumericField(string name, bool sortable = false, bool noIndex = false)
227-
: this(FieldName.Of(name), sortable, noIndex) { }
249+
internal NumericField(string name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
250+
: this(FieldName.Of(name), sortable, noIndex, missingIndex) { }
228251

229252
internal override void AddFieldTypeArgs(List<object> args)
230253
{
231254
if (NoIndex) args.Add(SearchArgs.NOINDEX);
232-
if (Sortable) args.Add(AttributeOptions.SORTABLE);
255+
if (Sortable) args.Add(FieldOptions.SORTABLE);
256+
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
233257
}
234258

235259
}
@@ -244,15 +268,18 @@ public enum VectorAlgo
244268

245269
public VectorAlgo Algorithm { get; }
246270
public Dictionary<string, object>? Attributes { get; }
247-
public VectorField(FieldName name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
271+
public bool MissingIndex { get; }
272+
273+
public VectorField(FieldName name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
248274
: base(name, FieldType.Vector)
249275
{
250276
Algorithm = algorithm;
251277
Attributes = attributes;
278+
MissingIndex = missingIndex;
252279
}
253280

254-
public VectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
255-
: this(FieldName.Of(name), algorithm, attributes) { }
281+
public VectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
282+
: this(FieldName.Of(name), algorithm, attributes, missingIndex) { }
256283

257284
internal override void AddFieldTypeArgs(List<object> args)
258285
{
@@ -267,6 +294,7 @@ internal override void AddFieldTypeArgs(List<object> args)
267294
args.Add(attribute.Value);
268295
}
269296
}
297+
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
270298
}
271299
}
272300
public List<Field> Fields { get; } = new List<Field>();
@@ -296,9 +324,9 @@ public Schema AddField(Field field)
296324
/// <param name="withSuffixTrie">Keeps a suffix trie with all terms which match the suffix.</param>
297325
/// <returns>The <see cref="Schema"/> object.</returns>
298326
public Schema AddTextField(string name, double weight = 1.0, bool sortable = false, bool unf = false, bool noStem = false,
299-
string? phonetic = null, bool noIndex = false, bool withSuffixTrie = false)
327+
string? phonetic = null, bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
300328
{
301-
Fields.Add(new TextField(name, weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie));
329+
Fields.Add(new TextField(name, weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie, missingIndex, emptyIndex));
302330
return this;
303331
}
304332

@@ -316,9 +344,9 @@ public Schema AddTextField(string name, double weight = 1.0, bool sortable = fal
316344
/// <param name="withSuffixTrie">Keeps a suffix trie with all terms which match the suffix.</param>
317345
/// <returns>The <see cref="Schema"/> object.</returns>
318346
public Schema AddTextField(FieldName name, double weight = 1.0, bool sortable = false, bool unf = false, bool noStem = false,
319-
string? phonetic = null, bool noIndex = false, bool withSuffixTrie = false)
347+
string? phonetic = null, bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
320348
{
321-
Fields.Add(new TextField(name, weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie));
349+
Fields.Add(new TextField(name, weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie, missingIndex, emptyIndex));
322350
return this;
323351
}
324352

@@ -328,9 +356,9 @@ public Schema AddTextField(FieldName name, double weight = 1.0, bool sortable =
328356
/// <param name="name">The field's name.</param>
329357
/// <param name="system">The coordinate system to use.</param>
330358
/// <returns>The <see cref="Schema"/> object.</returns>
331-
public Schema AddGeoShapeField(string name, CoordinateSystem system)
359+
public Schema AddGeoShapeField(string name, CoordinateSystem system, bool missingIndex = false)
332360
{
333-
Fields.Add(new GeoShapeField(name, system));
361+
Fields.Add(new GeoShapeField(name, system, missingIndex));
334362
return this;
335363
}
336364

@@ -340,9 +368,9 @@ public Schema AddGeoShapeField(string name, CoordinateSystem system)
340368
/// <param name="name">The field's name.</param>
341369
/// <param name="system">The coordinate system to use.</param>
342370
/// <returns>The <see cref="Schema"/> object.</returns>
343-
public Schema AddGeoShapeField(FieldName name, CoordinateSystem system)
371+
public Schema AddGeoShapeField(FieldName name, CoordinateSystem system, bool missingIndex = false)
344372
{
345-
Fields.Add(new GeoShapeField(name, system));
373+
Fields.Add(new GeoShapeField(name, system, missingIndex));
346374
return this;
347375
}
348376

@@ -353,9 +381,9 @@ public Schema AddGeoShapeField(FieldName name, CoordinateSystem system)
353381
/// <param name="sortable">If true, the text field can be sorted.</param>
354382
/// <param name="noIndex">Attributes can have the NOINDEX option, which means they will not be indexed.</param>
355383
/// <returns>The <see cref="Schema"/> object.</returns>
356-
public Schema AddGeoField(FieldName name, bool sortable = false, bool noIndex = false)
384+
public Schema AddGeoField(FieldName name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
357385
{
358-
Fields.Add(new GeoField(name, sortable, noIndex));
386+
Fields.Add(new GeoField(name, sortable, noIndex, missingIndex));
359387
return this;
360388
}
361389

@@ -366,9 +394,9 @@ public Schema AddGeoField(FieldName name, bool sortable = false, bool noIndex =
366394
/// <param name="sortable">If true, the text field can be sorted.</param>
367395
/// <param name="noIndex">Attributes can have the NOINDEX option, which means they will not be indexed.</param>
368396
/// <returns>The <see cref="Schema"/> object.</returns>
369-
public Schema AddGeoField(string name, bool sortable = false, bool noIndex = false)
397+
public Schema AddGeoField(string name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
370398
{
371-
Fields.Add(new GeoField(name, sortable, noIndex));
399+
Fields.Add(new GeoField(name, sortable, noIndex, missingIndex));
372400
return this;
373401
}
374402

@@ -379,9 +407,9 @@ public Schema AddGeoField(string name, bool sortable = false, bool noIndex = fal
379407
/// <param name="sortable">If true, the text field can be sorted.</param>
380408
/// <param name="noIndex">Attributes can have the NOINDEX option, which means they will not be indexed.</param>
381409
/// <returns>The <see cref="Schema"/> object.</returns>
382-
public Schema AddNumericField(FieldName name, bool sortable = false, bool noIndex = false)
410+
public Schema AddNumericField(FieldName name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
383411
{
384-
Fields.Add(new NumericField(name, sortable, noIndex));
412+
Fields.Add(new NumericField(name, sortable, noIndex, missingIndex));
385413
return this;
386414
}
387415

@@ -392,9 +420,9 @@ public Schema AddNumericField(FieldName name, bool sortable = false, bool noInde
392420
/// <param name="sortable">If true, the text field can be sorted.</param>
393421
/// <param name="noIndex">Attributes can have the NOINDEX option, which means they will not be indexed.</param>
394422
/// <returns>The <see cref="Schema"/> object.</returns>
395-
public Schema AddNumericField(string name, bool sortable = false, bool noIndex = false)
423+
public Schema AddNumericField(string name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
396424
{
397-
Fields.Add(new NumericField(name, sortable, noIndex));
425+
Fields.Add(new NumericField(name, sortable, noIndex, missingIndex));
398426
return this;
399427
}
400428

@@ -412,9 +440,9 @@ public Schema AddNumericField(string name, bool sortable = false, bool noIndex =
412440
/// <returns>The <see cref="Schema"/> object.</returns>
413441
public Schema AddTagField(FieldName name, bool sortable = false, bool unf = false,
414442
bool noIndex = false, string separator = ",",
415-
bool caseSensitive = false, bool withSuffixTrie = false)
443+
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
416444
{
417-
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie));
445+
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie, missingIndex, emptyIndex));
418446
return this;
419447
}
420448

@@ -432,9 +460,9 @@ public Schema AddTagField(FieldName name, bool sortable = false, bool unf = fals
432460
/// <returns>The <see cref="Schema"/> object.</returns>
433461
public Schema AddTagField(string name, bool sortable = false, bool unf = false,
434462
bool noIndex = false, string separator = ",",
435-
bool caseSensitive = false, bool withSuffixTrie = false)
463+
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
436464
{
437-
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie));
465+
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie, missingIndex, emptyIndex));
438466
return this;
439467
}
440468

@@ -445,9 +473,9 @@ public Schema AddTagField(string name, bool sortable = false, bool unf = false,
445473
/// <param name="algorithm">The vector similarity algorithm to use.</param>
446474
/// <param name="attribute">The algorithm attributes for the creation of the vector index.</param>
447475
/// <returns>The <see cref="Schema"/> object.</returns>
448-
public Schema AddVectorField(FieldName name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
476+
public Schema AddVectorField(FieldName name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
449477
{
450-
Fields.Add(new VectorField(name, algorithm, attributes));
478+
Fields.Add(new VectorField(name, algorithm, attributes, missingIndex));
451479
return this;
452480
}
453481

@@ -458,9 +486,9 @@ public Schema AddVectorField(FieldName name, VectorAlgo algorithm, Dictionary<st
458486
/// <param name="algorithm">The vector similarity algorithm to use.</param>
459487
/// <param name="attribute">The algorithm attributes for the creation of the vector index.</param>
460488
/// <returns>The <see cref="Schema"/> object.</returns>
461-
public Schema AddVectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
489+
public Schema AddVectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
462490
{
463-
Fields.Add(new VectorField(name, algorithm, attributes));
491+
Fields.Add(new VectorField(name, algorithm, attributes, missingIndex));
464492
return this;
465493
}
466494
}

0 commit comments

Comments
 (0)