Skip to content
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
88 changes: 56 additions & 32 deletions src/DataStax.AstraDB.DataApi/Tables/TableIndexBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,45 +24,67 @@ namespace DataStax.AstraDB.DataApi.Tables;
public class TableIndexBuilder
{
/// <summary>
/// Create a default index.
/// Create a default table index.
/// </summary>
/// <returns></returns>
public TableIndexDefinition Index(bool caseSensitive = true, bool normalize = false, bool ascii = false)
/// <param name="options">A <see cref="TableIndexOptions"/> specification for the indexing options. Pass null for defaults</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableIndexDefinition Index(TableIndexOptions options = null)
{
return new TableIndexDefinition
{
Options = new TableIndexOptions {
CaseSensitive = caseSensitive,
Normalize = normalize,
Ascii = ascii
Options = options ?? new TableIndexOptions
{
CaseSensitive = true,
Normalize = false,
Ascii = false
}
};
}

/// <summary>
/// Create a table index for a map column.
/// </summary>
/// <param name="mapIndexType"></param>
/// <returns></returns>
/// <param name="mapIndexType">A <see cref="MapIndexType"/> value specifying how the map is indexed (keys, values or entries).</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableIndexDefinition Map(MapIndexType mapIndexType)
{
return new TableMapIndexDefinition(mapIndexType);
}

/// <summary>
/// Create a text index using the default analyzer.
/// Create a table index for a map column.
/// </summary>
/// <returns></returns>
/// <param name="mapIndexType">A <see cref="MapIndexType"/> value specifying how the map is indexed (keys, values or entries).</param>
/// <param name="options">A <see cref="TableIndexOptions"/> specification for the indexing options. Pass null for defaults</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableIndexDefinition Map(MapIndexType mapIndexType, TableIndexOptions options = null)
{
return new TableMapIndexDefinition(
mapIndexType,
options ?? new TableIndexOptions
{
CaseSensitive = true,
Normalize = false,
Ascii = false
}
);
}

/// <summary>
/// Create a table text index using the default analyzer.
/// </summary>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableTextIndexDefinition Text()
{
return new TableTextIndexDefinition();
}

/// <summary>
/// Create a text index using a specific analyzer.
/// Create a table text index using a specific analyzer.
/// See https://docs.datastax.com/en/astra-db-serverless/databases/analyzers.html#supported-built-in-analyzers
/// </summary>
/// <param name="analyzer"></param>
/// <returns></returns>
/// <param name="analyzer">A <see cref="TextAnalyzer"/> value specifying a preset indexing method.</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableTextIndexDefinition Text(TextAnalyzer analyzer)
{
return new TableTextIndexDefinition()
Expand All @@ -74,11 +96,11 @@ public TableTextIndexDefinition Text(TextAnalyzer analyzer)
}

/// <summary>
/// Create a text index using a specific analyzer by name, for example a language-specific analyzer.
/// Create a table text index using a specific analyzer by name, for example a language-specific analyzer.
/// See https://docs.datastax.com/en/astra-db-serverless/databases/analyzers.html#supported-built-in-analyzers
/// </summary>
/// <param name="analyzer"></param>
/// <returns></returns>
/// <param name="analyzer">A string value specifying a preset indexing method.</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableTextIndexDefinition Text(string analyzer)
{
return new TableTextIndexDefinition()
Expand All @@ -90,10 +112,11 @@ public TableTextIndexDefinition Text(string analyzer)
}

/// <summary>
/// Create a text index using custom analyzer options.
/// Create a table text index using custom analyzer options.
/// See https://docs.datastax.com/en/astra-db-serverless/databases/analyzers.html#supported-built-in-analyzers
/// </summary>
/// <param name="analyzerOptions"></param>
/// <returns></returns>
/// <param name="analyzerOptions">An <see cref="AnalyzerOptions"/> object defining the analyzer options for the indexing.</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableTextIndexDefinition Text(AnalyzerOptions analyzerOptions)
{
return new TableTextIndexDefinition()
Expand All @@ -105,10 +128,11 @@ public TableTextIndexDefinition Text(AnalyzerOptions analyzerOptions)
}

/// <summary>
/// Create a text index with free-form analyzer options.
/// Create a table text index using custom, free-form analyzer options.
/// See https://docs.datastax.com/en/astra-db-serverless/databases/analyzers.html#supported-built-in-analyzers
/// </summary>
/// <param name="analyzer"></param>
/// <returns></returns>
/// <param name="analyzer">A free-form object defining the analyzer options for the indexing.</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableTextIndexDefinition Text(object analyzer)
{
return new TableTextIndexDefinition()
Expand All @@ -120,40 +144,40 @@ public TableTextIndexDefinition Text(object analyzer)
}

/// <summary>
/// Create a vector index.
/// Create a table vector index.
/// </summary>
/// <returns></returns>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableVectorIndexDefinition Vector()
{
return Vector(null, null);
}

/// <summary>
/// Create a vector index.
/// Create a table vector index.
/// </summary>
/// <param name="metric">Optional similarity metric to use for vector searches on this index</param>
/// <returns></returns>
/// <param name="metric">Similarity metric to use for vector searches on this index</param>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableVectorIndexDefinition Vector(SimilarityMetric metric)
{
return Vector(metric, null);
}

/// <summary>
/// Create a vector index.
/// Create a table vector index.
/// </summary>
/// <param name="sourceModel">Allows enabling certain vector optimizations on the index by specifying the source model for your vectors</param>
/// <returns></returns>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableVectorIndexDefinition Vector(string sourceModel)
{
return Vector(null, sourceModel);
}

/// <summary>
/// Create a vector index.
/// Create a table vector index.
/// </summary>
/// <param name="metric">Similarity metric to use for vector searches on this index</param>
/// <param name="sourceModel">Allows enabling certain vector optimizations on the index by specifying the source model for your vectors. Pass a null for server default.</param>
/// <returns></returns>
/// <returns>An index definition for use in a <see cref="Table{T}"/> CreateIndex method call.</returns>
public TableVectorIndexDefinition Vector(SimilarityMetric? metric, string sourceModel)
{
return new TableVectorIndexDefinition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ internal TableMapIndexDefinition(MapIndexType indexType)
IndexType = indexType;
}

internal TableMapIndexDefinition(MapIndexType indexType, TableIndexOptions options)
{
IndexType = indexType;
Options = options;
}

/// <summary>
/// The column to index.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,16 @@ public async Task CreateIndexTests_WithOptions_WithBuilder()
{
var table = await fixture.Database.CreateTableAsync<RowEventByDay>(tableName);
string indexName = "category_idx";
var indexDefinition = new TableIndexDefinition() { Options = new TableIndexOptions { Ascii = true, CaseSensitive = true, Normalize = true } };

await table.CreateIndexAsync(indexName, (b) => b.Category, Builders.TableIndex.Index(true, true, true));
// compare: {"createIndex":{"name":"category_idx","definition":{"column":"category","options":{"ascii":true,"caseSensitive":true,"normalize":true}}}}
await table.CreateIndexAsync(indexName, (b) => b.Category,
Builders.TableIndex.Index(new TableIndexOptions
{
CaseSensitive = true,
Normalize = true,
Ascii = true
}
));
// compare: {"createIndex":{"name":"category_idx","definition":{"options":{"caseSensitive":true,"normalize":true,"ascii":true},"column":"category"}}}

var result = await table.ListIndexesAsync();
var foundIndex = result.Single(i => i.Name == indexName);
Expand Down Expand Up @@ -260,9 +266,9 @@ public async Task CreateIndexTests_MapIndex_EntriesExplicitly()
}

[Fact]
public async Task CreateIndexTests_MapIndex_Keys()
public async Task CreateIndexTests_MapIndex_KeysNoOptions()
{
var tableName = "tableIndexesTest_MapIndex_Keys";
var tableName = "CreateIndexTests_MapIndex_KeysNoOptions";
string indexName = "map_k_idx";

try
Expand All @@ -286,9 +292,47 @@ public async Task CreateIndexTests_MapIndex_Keys()
}

[Fact]
public async Task CreateIndexTests_MapIndex_Values()
public async Task CreateIndexTests_MapIndex_KeysWithOptions()
{
var tableName = "tableIndexesTest_MapIndex_Values";
var tableName = "CreateIndexTests_MapIndex_KeysWithOptions";
string indexName = "map_k_idx";

try
{
var table = await fixture.Database.CreateTableAsync<TableMapTest>(tableName);

await table.CreateIndexAsync(indexName, (b) => b.StringMap,
Builders.TableIndex.Map(MapIndexType.Keys, new TableIndexOptions
{
CaseSensitive = true,
Normalize = true,
Ascii = true
}
));
// compare: {"createIndex":{"name":"map_k_idx","definition":{"column":{"StringMap":"$keys"},"options":{"caseSensitive":true,"normalize":true,"ascii":true}}}}

var result = await table.ListIndexesAsync();
var foundIndex = result.Single(i => i.Name == indexName);
Assert.NotNull(foundIndex);
Assert.IsType<TableIndexDefinition>(foundIndex.Definition);
Assert.Equal(new Dictionary<string,string> { ["StringMap"] = "$keys" }, foundIndex.Definition.Column);
var indexDefinition = (TableIndexDefinition)foundIndex.Definition;
Assert.NotNull(indexDefinition.Options);
Assert.True(indexDefinition.Options.CaseSensitive);
Assert.True(indexDefinition.Options.Normalize);
Assert.True(indexDefinition.Options.Ascii);

}
finally
{
await fixture.Database.DropTableAsync(tableName);
}
}

[Fact]
public async Task CreateIndexTests_MapIndex_ValuesNoOptions()
{
var tableName = "CreateIndexTests_MapIndex_ValuesNoOptions";
string indexName = "map_v_idx";

try
Expand All @@ -311,6 +355,45 @@ public async Task CreateIndexTests_MapIndex_Values()
}
}

[Fact]
public async Task CreateIndexTests_MapIndex_ValuesWithOptions()
{
var tableName = "tableIndexesTest_MapIndex_Values";
string indexName = "map_v_idx";

try
{
var table = await fixture.Database.CreateTableAsync<TableMapTest>(tableName);

await table.CreateIndexAsync(
indexName, (b) => b.StringMap,
Builders.TableIndex.Map(MapIndexType.Values, new TableIndexOptions
{
CaseSensitive = true,
Normalize = true,
Ascii = true
}
));
// compare: {"createIndex":{"name":"map_v_idx","definition":{"column":{"StringMap":"$values"},"options":{"caseSensitive":true,"normalize":true,"ascii":true}}}}

var result = await table.ListIndexesAsync();
var foundIndex = result.Single(i => i.Name == indexName);
Assert.NotNull(foundIndex);
Assert.IsType<TableIndexDefinition>(foundIndex.Definition);
Assert.Equal(new Dictionary<string,string> { ["StringMap"] = "$values" }, foundIndex.Definition.Column);
var indexDefinition = (TableIndexDefinition)foundIndex.Definition;
Assert.NotNull(indexDefinition.Options);
Assert.True(indexDefinition.Options.CaseSensitive);
Assert.True(indexDefinition.Options.Normalize);
Assert.True(indexDefinition.Options.Ascii);

}
finally
{
await fixture.Database.DropTableAsync(tableName);
}
}

[Fact]
public async Task CreateIndexTests_VectorIndex_NoOptions()
{
Expand Down Expand Up @@ -648,7 +731,7 @@ await table.CreateTextIndexAsync(indexName, (b) => b.Name, Builders.TableIndex.T

}

// [SkipWhenAstra] // TODO: reinstate this attribute once 115 is merged
[SkipWhenAstra]
[Fact(Skip="Run manually on HCD after some CQL setup!")]
public async Task ListIndexesTests_UnknownUnsupportedCQLIndex()
{
Expand Down
Loading