Hello, I am not sure on how to query a setname based on multiple filters and aggregate the results count based on some values.
For the sake of the argument, let’s suppose that the dataset has this structure:
CUSTOMER_ID; TIMESTAMP; STATUS
-
CUSTOMER_ID
andTIMESTAMP
can be optional input values via web api. They are the fields to be filtered.
-
STATUS
is an enum with 7 different values. It is the field to run the aggregation on. The output should give the total count for each of those values.
Reading the docs/forum, this is the approach I am using:
- Set filter on most selective criteria
var stmt = new Statement();
stmt.SetFilter(Filter.Equal(mainFilterBin, customerId));
- Define a UDF via Lua script that additionally filters the records based on
TIMESTAMP
and aggregate the count, returning a map. The invocation is something like:
var rs = client.QueryAggregate(null, stmt, luaPackageName, luaFunctionName,
Value.Get(startDtUnixTs), Value.Get(endDtUnixTs));
The approach works, I am able to query the dataset as I want to, but I would like to know if there is a better a approach for applying multiple filtering before running LUA.
So, I want to know how to apply multiple filters via c# code and then using LUA for aggregation of the resulting record set on some field.
Some additional info:
-
I am using Aerospike Client v 4.2.7, I do not want to use PredExp because it is obsolete.
-
I read about Expressions and how to set them in a Policy (e.g.;
multiFilterPolicy
). But then runningvar rs = client.QueryAggregate(multiFilerPolicy, stmt, luaPackageName, luaFunctionName)
won’t work, throwingQuery Failed: Error 16 Unsupported server feature
.
Also about this, I must use the synchronous client since the asnyc doesn’t supportQueryAggregate
(discussion).
I could skip LUA scripting but is applying something like this fine? I’m not sure because it seems that in this case i would need to count the differentSTATUS
records in the while loop.
stmt.SetFilter(Filter.Range(binName, begin, end));
// Predicates are applied on query results on server side.
// Predicates can reference any bin.
QueryPolicy policy = new QueryPolicy(client.queryPolicyDefault);
policy.filterExp = Exp.Build(
Exp.Or(
Exp.And(
Exp.EQ(Exp.StringBin("customerId"), Exp.Val(customerId)),
Exp.GE(Exp.IntBin("timestamp"), Exp.Val(timestamp)))
));
RecordSet rs = client.Query(policy, stmt);
try
{
while (rs.Next())
{
Record record = rs.Record;
console.Info("Record: " + record.ToString());
}
}
finally
{
rs.Close();
}
What is the best approach in this case? Do you have any suggestion?
Thank you very much