String Conditional Query?

Im trying to write a conditional query for searching for a string in a char vector array in the C# Api. Whats the best way of going about this or are char searches only possible?
At the moment i try to add the condition with:

TileDB.QueryCondition qc = TileDb.QueryCondition.create_for_datatype(ctx, TileDb.DataType.TILEDB_STRING_ASCII, “dim1”, “Test”, TileDB.QueryConditionOperatorType.TILEDB_EQ);
query.set_condition(qc)
query.submit();

When running however i get a microsoft visual c++ runtime error #3, saying result has not been initialised?

Thanks for trying to search a string. We did find a bug for string searching and already uploaded a new version of nuget package. You can download the nuget package(dotnet add package TileDB.CSharp --version 2.4.5) and retry it. We also added two examples for QueryCondition with string.

  1. TileDB-CSharp/ExampleQueryCondition.cs at main · TileDB-Inc/TileDB-CSharp · GitHub
    This example is for querying with conditional integer and string clauses. Note that we need to initialize the data vectors with enough elements on Line 147 and Line 149.

  2. TileDB-CSharp/ExampleQueryCondition2.cs at main · TileDB-Inc/TileDB-CSharp · GitHub
    This example has the same data set, but uses a convenient class TileDBBuffer to handle buffers.
    The TileDBBuffer class will help to handle offsets and validities. For POD data type(such as integer, double, etc), it will not use extra memory(zero copy). For string type, it does uses extra memory for encoding between c type ascii char and c# char.

Please let us know if the above solves the problem or not. If you have any other suggestions or need more demo examples, please let us know. Thanks

1 Like

Thank you so much for your help! I apologise for the late reply, but i have managed to get a string search working for my sparse array but i am encountering an issue with looping. For my code, i need to search one string at a time over and over, but i find when i submit my query more then once the search condition does not work.

A simplified version looks like this:

for(int i=0;i<10;i++)
{
    TileDB.QueryCondition qc = TileDB.QueryCondition.create_for_datatype(ctx, TileDB.DataType.TILEDB_INT32, "a1", string_list[i], TileDB.QueryConditionOperatorType.TILEDB_EQ);
    query.set_condition(qc);
    query.submit();
    Console.WriteLine(String.Concat(String.Join("", a1_data).Where(c => !Char.IsWhiteSpace(c)));
}

The string_list is a list of strings that i have written to the array, and when searching for any index in that list it will work for the first query. But if i try to search for another string it will return no results.

The print statement just prints everything except whitespace for a1_data which is my char attribute.

Hi there,

You have two options here:

  • You must create a new query in each iteration. Setting the query condition does not re-initialize the query, which is something we need to think about at the core.
  • You can use multi-range queries and submit all strings at once. That will be (much) faster. @Bin_Deng can follow up on how to do that in C#, as our docs are a bit behind.
1 Like

Unfortunately, query could not be re-used. Could you try this:
for(int i=0;i<10;i++)
{
var query= new new TileDB.Query(ctx, array_read, TileDB.QueryType.TILEDB_READ);
query.set_layout(…);
query.set_buffer(…);

TileDB.QueryCondition qc = TileDB.QueryCondition.create_for_datatype(ctx, 

TileDB.DataType.TILEDB_INT32, “a1”, string_list[i],
TileDB.QueryConditionOperatorType.TILEDB_EQ);
query.set_condition(qc);
query.submit();
Console.WriteLine(String.Concat(String.Join("", a1_data).Where(c => !Char.IsWhiteSpace(c)));
}

I just updated the example code for TileDB-CSharp/ExampleQueryCondition.cs at main · TileDB-Inc/TileDB-CSharp · GitHub. You can have a look at it. If you still have problems for that, Please let me know.

1 Like

Added an example for multi-range queries(TileDB-CSharp/ExampleStringMultiRangeQuery.cs at main · TileDB-Inc/TileDB-CSharp · GitHub). Note that add_range is only for dimensions(not for attributes). For attributes, we still need to use QueryCondition.