Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for index and search with missing / empty values #315

Merged
merged 4 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
namespace NRedisStack.Search.Literals;

internal class AttributeOptions
internal class FieldOptions
{
public const string SORTABLE = "SORTABLE";
public const string UNF = "UNF";
public const string NOSTEM = "NOSTEM";
public const string NOINDEX = "NOINDEX";
public const string INDEXEMPTY = "INDEXEMPTY";
public const string INDEXMISSING = "INDEXMISSING";

//TODO: add all options
}
120 changes: 74 additions & 46 deletions src/NRedisStack/Search/Schema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ public class TextField : Field
public bool Unf { get; }
public bool NoIndex { get; }
public bool WithSuffixTrie { get; }
public bool MissingIndex { get; }
public bool EmptyIndex { get; }

public TextField(FieldName name, double weight = 1.0, bool noStem = false,
string? phonetic = null, bool sortable = false, bool unf = false,
bool noIndex = false, bool withSuffixTrie = false)
bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
: base(name, FieldType.Text)
{
Weight = weight;
Expand All @@ -79,12 +81,14 @@ public TextField(FieldName name, double weight = 1.0, bool noStem = false,
Unf = unf;
NoIndex = noIndex;
WithSuffixTrie = withSuffixTrie;
MissingIndex = missingIndex;
EmptyIndex = emptyIndex;
}

public TextField(string name, double weight = 1.0, bool noStem = false,
string? phonetic = null, bool sortable = false, bool unf = false,
bool noIndex = false, bool withSuffixTrie = false)
: this(FieldName.Of(name), weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie) { }
bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
: this(FieldName.Of(name), weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie, missingIndex, emptyIndex) { }

internal override void AddFieldTypeArgs(List<object> args)
{
Expand All @@ -93,8 +97,11 @@ internal override void AddFieldTypeArgs(List<object> args)
AddPhonetic(args);
AddWeight(args);
if (WithSuffixTrie) args.Add(SearchArgs.WITHSUFFIXTRIE);
if (Sortable) args.Add(AttributeOptions.SORTABLE);
if (Sortable) args.Add(FieldOptions.SORTABLE);
if (Unf) args.Add(SearchArgs.UNF);
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
if (EmptyIndex) args.Add(FieldOptions.INDEXEMPTY);

}

private void AddWeight(List<object> args)
Expand Down Expand Up @@ -124,10 +131,12 @@ public class TagField : Field
public string Separator { get; }
public bool CaseSensitive { get; }
public bool WithSuffixTrie { get; }
public bool MissingIndex { get; }
public bool EmptyIndex { get; }

internal TagField(FieldName name, bool sortable = false, bool unf = false,
bool noIndex = false, string separator = ",",
bool caseSensitive = false, bool withSuffixTrie = false)
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
: base(name, FieldType.Tag)
{
Sortable = sortable;
Expand All @@ -136,12 +145,14 @@ internal TagField(FieldName name, bool sortable = false, bool unf = false,
Separator = separator;
CaseSensitive = caseSensitive;
WithSuffixTrie = withSuffixTrie;
EmptyIndex = emptyIndex;
MissingIndex = missingIndex;
}

internal TagField(string name, bool sortable = false, bool unf = false,
bool noIndex = false, string separator = ",",
bool caseSensitive = false, bool withSuffixTrie = false)
: this(FieldName.Of(name), sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie) { }
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
: this(FieldName.Of(name), sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie, missingIndex, emptyIndex) { }

internal override void AddFieldTypeArgs(List<object> args)
{
Expand All @@ -154,29 +165,35 @@ internal override void AddFieldTypeArgs(List<object> args)
args.Add(Separator);
}
if (CaseSensitive) args.Add(SearchArgs.CASESENSITIVE);
if (Sortable) args.Add(AttributeOptions.SORTABLE);
if (Sortable) args.Add(FieldOptions.SORTABLE);
if (Unf) args.Add(SearchArgs.UNF);
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
if (EmptyIndex) args.Add(FieldOptions.INDEXEMPTY);
}
}

public class GeoField : Field
{
public bool Sortable { get; }
public bool NoIndex { get; }
internal GeoField(FieldName name, bool sortable = false, bool noIndex = false)
public bool MissingIndex { get; }

internal GeoField(FieldName name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
: base(name, FieldType.Geo)
{
Sortable = sortable;
NoIndex = noIndex;
MissingIndex = missingIndex;
}

internal GeoField(string name, bool sortable = false, bool noIndex = false)
: this(FieldName.Of(name), sortable, noIndex) { }
internal GeoField(string name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
: this(FieldName.Of(name), sortable, noIndex, missingIndex) { }

internal override void AddFieldTypeArgs(List<object> args)
{
if (NoIndex) args.Add(SearchArgs.NOINDEX);
if (Sortable) args.Add(AttributeOptions.SORTABLE);
if (Sortable) args.Add(FieldOptions.SORTABLE);
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
}

}
Expand All @@ -196,40 +213,47 @@ public enum CoordinateSystem
SPHERICAL
}
private CoordinateSystem system { get; }
public bool MissingIndex { get; }

internal GeoShapeField(FieldName name, CoordinateSystem system)
internal GeoShapeField(FieldName name, CoordinateSystem system, bool missingIndex = false)
: base(name, FieldType.GeoShape)
{
this.system = system;
MissingIndex = missingIndex;
}

internal GeoShapeField(string name, CoordinateSystem system)
: this(FieldName.Of(name), system) { }
internal GeoShapeField(string name, CoordinateSystem system, bool missingIndex = false)
: this(FieldName.Of(name), system, missingIndex) { }

internal override void AddFieldTypeArgs(List<object> args)
{
args.Add(system.ToString());
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
}
}

public class NumericField : Field
{
public bool Sortable { get; }
public bool NoIndex { get; }
internal NumericField(FieldName name, bool sortable = false, bool noIndex = false)
public bool MissingIndex { get; }

internal NumericField(FieldName name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
: base(name, FieldType.Numeric)
{
Sortable = sortable;
NoIndex = noIndex;
MissingIndex = missingIndex;
}

internal NumericField(string name, bool sortable = false, bool noIndex = false)
: this(FieldName.Of(name), sortable, noIndex) { }
internal NumericField(string name, bool sortable = false, bool noIndex = false, bool missingIndex = false)
: this(FieldName.Of(name), sortable, noIndex, missingIndex) { }

internal override void AddFieldTypeArgs(List<object> args)
{
if (NoIndex) args.Add(SearchArgs.NOINDEX);
if (Sortable) args.Add(AttributeOptions.SORTABLE);
if (Sortable) args.Add(FieldOptions.SORTABLE);
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
}

}
Expand All @@ -244,15 +268,18 @@ public enum VectorAlgo

public VectorAlgo Algorithm { get; }
public Dictionary<string, object>? Attributes { get; }
public VectorField(FieldName name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
public bool MissingIndex { get; }

public VectorField(FieldName name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
: base(name, FieldType.Vector)
{
Algorithm = algorithm;
Attributes = attributes;
MissingIndex = missingIndex;
}

public VectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
: this(FieldName.Of(name), algorithm, attributes) { }
public VectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
: this(FieldName.Of(name), algorithm, attributes, missingIndex) { }

internal override void AddFieldTypeArgs(List<object> args)
{
Expand All @@ -267,6 +294,7 @@ internal override void AddFieldTypeArgs(List<object> args)
args.Add(attribute.Value);
}
}
if (MissingIndex) args.Add(FieldOptions.INDEXMISSING);
}
}
public List<Field> Fields { get; } = new List<Field>();
Expand Down Expand Up @@ -296,9 +324,9 @@ public Schema AddField(Field field)
/// <param name="withSuffixTrie">Keeps a suffix trie with all terms which match the suffix.</param>
/// <returns>The <see cref="Schema"/> object.</returns>
public Schema AddTextField(string name, double weight = 1.0, bool sortable = false, bool unf = false, bool noStem = false,
string? phonetic = null, bool noIndex = false, bool withSuffixTrie = false)
string? phonetic = null, bool noIndex = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
{
Fields.Add(new TextField(name, weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie));
Fields.Add(new TextField(name, weight, noStem, phonetic, sortable, unf, noIndex, withSuffixTrie, missingIndex, emptyIndex));
return this;
}

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

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

Expand All @@ -340,9 +368,9 @@ public Schema AddGeoShapeField(string name, CoordinateSystem system)
/// <param name="name">The field's name.</param>
/// <param name="system">The coordinate system to use.</param>
/// <returns>The <see cref="Schema"/> object.</returns>
public Schema AddGeoShapeField(FieldName name, CoordinateSystem system)
public Schema AddGeoShapeField(FieldName name, CoordinateSystem system, bool missingIndex = false)
{
Fields.Add(new GeoShapeField(name, system));
Fields.Add(new GeoShapeField(name, system, missingIndex));
return this;
}

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

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

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

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

Expand All @@ -412,9 +440,9 @@ public Schema AddNumericField(string name, bool sortable = false, bool noIndex =
/// <returns>The <see cref="Schema"/> object.</returns>
public Schema AddTagField(FieldName name, bool sortable = false, bool unf = false,
bool noIndex = false, string separator = ",",
bool caseSensitive = false, bool withSuffixTrie = false)
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
{
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie));
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie, missingIndex, emptyIndex));
return this;
}

Expand All @@ -432,9 +460,9 @@ public Schema AddTagField(FieldName name, bool sortable = false, bool unf = fals
/// <returns>The <see cref="Schema"/> object.</returns>
public Schema AddTagField(string name, bool sortable = false, bool unf = false,
bool noIndex = false, string separator = ",",
bool caseSensitive = false, bool withSuffixTrie = false)
bool caseSensitive = false, bool withSuffixTrie = false, bool missingIndex = false, bool emptyIndex = false)
{
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie));
Fields.Add(new TagField(name, sortable, unf, noIndex, separator, caseSensitive, withSuffixTrie, missingIndex, emptyIndex));
return this;
}

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

Expand All @@ -458,9 +486,9 @@ public Schema AddVectorField(FieldName name, VectorAlgo algorithm, Dictionary<st
/// <param name="algorithm">The vector similarity algorithm to use.</param>
/// <param name="attribute">The algorithm attributes for the creation of the vector index.</param>
/// <returns>The <see cref="Schema"/> object.</returns>
public Schema AddVectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null)
public Schema AddVectorField(string name, VectorAlgo algorithm, Dictionary<string, object>? attributes = null, bool missingIndex = false)
{
Fields.Add(new VectorField(name, algorithm, attributes));
Fields.Add(new VectorField(name, algorithm, attributes, missingIndex));
return this;
}
}
Expand Down
Loading
Loading