Let me walk you through a simple example with different options for querying.
My test data:
Initialized the client and connected to the cluster.
key0 : (gen:1),(exp:455917634),(bins:(name:Sandra),(age:34))
key1 : (gen:1),(exp:455917634),(bins:(name:Jack),(age:26))
key2 : (gen:1),(exp:455917634),(bins:(name:Jill),(age:20))
key3 : (gen:1),(exp:455917634),(bins:(name:James),(age:38))
key4 : (gen:1),(exp:455917634),(bins:(name:Jim),(age:46))
key5 : (gen:1),(exp:455917634),(bins:(name:Julia),(age:62))
key6 : (gen:1),(exp:455917634),(bins:(name:Sally),(age:32))
key7 : (gen:1),(exp:455917634),(bins:(name:Sean),(age:24))
key8 : (gen:1),(exp:455917634),(bins:(name:Sam),(age:12))
key9 : (gen:1),(exp:455917634),(bins:(name:Susan),(age:42))
I will omit all the import statements - just show the relevant code:
Basic Query: Find all records where age between 20 and 30.
Code:
//Run SI query
Statement stmt = new Statement();
stmt.setNamespace("test");
stmt.setSetName("testset");
stmt.setFilter(Filter.range("age", 20,30));
QueryPolicy qp = new QueryPolicy();
RecordSet rs = client.query(qp, stmt);
WritePolicy wp = new WritePolicy();
int nCount = 0;
while(rs.next()){
Record r = rs.getRecord();
Key thisKey = rs.getKey();
System.out.println(r);
}
Output:
(gen:1),(exp:455917634),(bins:(name:Sean),(age:24))
(gen:1),(exp:455917634),(bins:(name:Jill),(age:20))
(gen:1),(exp:455917634),(bins:(name:Jack),(age:26))
Modify the query to only return when name starts with S.
Find all records where age between 20 and 30 AND name starts with S.
Code:
Statement stmt = new Statement();
stmt.setNamespace("test");
stmt.setSetName("testset");
stmt.setFilter(Filter.range("age", 20,30));
Expression nameExp = Exp.build(
Exp.regexCompare("^S.*", RegexFlag.ICASE|RegexFlag.NEWLINE, Exp.stringBin("name"))
);
QueryPolicy qp = new QueryPolicy();
qp.filterExp = nameExp;
RecordSet rs = client.query(qp, stmt);
while(rs.next()){
Record r = rs.getRecord();
Key thisKey = rs.getKey();
System.out.println(r);
}
Output:
(gen:1),(exp:455917634),(bins:(name:Sean),(age:24))
If instead of AND you want OR - its no longer a Secondary Index assisted query. We must scan every record.
Find all records where age between 20 and 30 OR name starts with S.
Code:
Statement stmt = new Statement();
stmt.setNamespace("test");
stmt.setSetName("testset");
stmt.setFilter(null);
Expression nameExp = Exp.build(
Exp.or(
Exp.regexCompare("^S.*", RegexFlag.ICASE|RegexFlag.NEWLINE, Exp.stringBin("name")),
Exp.and(
Exp.gt(Exp.intBin("age"), Exp.val(20)),
Exp.lt(Exp.intBin("age"), Exp.val(30)))
)
);
QueryPolicy qp = new QueryPolicy();
qp.filterExp = nameExp;
RecordSet rs = client.query(qp, stmt);
while(rs.next()){
Record r = rs.getRecord();
Key thisKey = rs.getKey();
System.out.println(r);
}
Output:
(gen:1),(exp:455917634),(bins:(name:Sandra),(age:34))
(gen:1),(exp:455917634),(bins:(name:Susan),(age:42))
(gen:1),(exp:455917634),(bins:(name:Sally),(age:32))
(gen:1),(exp:455917634),(bins:(name:Sean),(age:24))
(gen:1),(exp:455917634),(bins:(name:Jack),(age:26))
(gen:1),(exp:455917634),(bins:(name:Sam),(age:12))
Hope that explains the different query constructs.