Query Conditions

Query conditions can selectively return data that meets a given expression. Rather than filter the results after a query, a condition is pushed down to TileDB and returns a subset of the valid elements.

tiledb_ctx_t * ctx;
tiledb_ctx_alloc(NULL, &ctx);

tiledb_array_t* array_read;
tiledb_array_alloc(ctx, "<array_uri>", &array_read);
tiledb_array_open(ctx, array_read, TILEDB_READ);

// Query condition where a1 != NULL
tiledb_query_condition_t* queryCondition1;
tiledb_query_condition_alloc(ctx, &queryCondition1);
tiledb_query_condition_init(ctx, queryCondition1, "a1", NULL, 0, TILEDB_NE);

// Query condition where a2 > 10.5
float conditionVal = 10.5f;
tiledb_query_condition_t* queryCondition2;
tiledb_query_condition_alloc(ctx, &queryCondition2);
tiledb_query_condition_init(ctx, queryCondition2, "a2", &conditionVal, sizeof(float), TILEDB_GT);

// Query condition where (a1 != NULL || a2 > 10.5)
tiledb_query_condition_t* queryCondition;
tiledb_query_condition_alloc(ctx, &queryCondition);
tiledb_query_condition_combine(ctx, queryCondition1, queryCondition2, TILEDB_OR, &queryCondition);

// Slice rows 1, 2 and cols 2, 3, 4
int32_t subarray_ranges[] = {1, 2, 2, 4};
tiledb_subarray_t* subarray;
tiledb_subarray_alloc(ctx, array_read, &subarray);
tiledb_subarray_set_subarray(ctx, subarray, subarray_ranges);

// Allocate buffers for query
int32_t a1_read[6];
uint64_t a1_read_size = sizeof(a1_read);
uint8_t a1_read_validity[6];
uint64_t a1_read_validity_size = sizeof(a1_read_validity);
float a2_read[6];
uint64_t a2_read_size = sizeof(a2_read);

tiledb_query_t* query_read;
tiledb_query_alloc(ctx, array_read, TILEDB_READ, &query_read);
tiledb_query_set_layout(ctx, query_read, TILEDB_ROW_MAJOR);
tiledb_query_set_data_buffer(ctx, query_read, "a1", a1_read, &a1_read_size);
tiledb_query_set_validity_buffer(ctx, query_read, "a1", a1_read_validity, &a1_read_validity_size);
tiledb_query_set_data_buffer(ctx, query_read, "a2", a2_read, &a2_read_size);
tiledb_query_set_subarray_t(ctx, query_read, subarray);
tiledb_query_set_condition(ctx, query_read, queryCondition);
tiledb_query_submit(ctx, query_read);

// For sparse arrays, a1_read_size will be set to number of bytes read into the buffer
// + Values that don't meet the query condition won't be read, so we can use byte math to get a1_result_num
int a1_result_num = (int)(a1_read_size / sizeof(int32_t));
for (size_t i = 0; i < a1_result_num; i++) {
    // Print buffers from sparse array...
}

// For dense arrays, we can use the fill value of an attribute to check the element met our conditions
tiledb_array_schema_t* schema;
tiledb_array_get_schema(ctx, array_read, &schema);
tiledb_attribute_t* attr;
tiledb_array_schema_get_attribute_from_name(ctx, schema, "a2", &attr);
float* fillVal;
uint64_t valSize;
tiledb_attribute_get_fill_value(ctx, attr, &fillVal, &valSize);
for (size_t i = 0; i < a2_read_size / sizeof(float); i++) {
    if (a2_read[i] != *fillVal) {
        // Print buffers from dense array...
    }
}

// Free allocated objects
tiledb_array_free(&array_read);
tiledb_query_condition_free(&queryCondition1);
tiledb_query_condition_free(&queryCondition2);
tiledb_query_condition_free(&queryCondition);
tiledb_subarray_free(&subarray);
tiledb_query_free(&query_read);

Last updated