Skip to content

Implementation of SQL SELECT for Aerospike Predicate Filter API

License

Notifications You must be signed in to change notification settings

PastorGL/AQLSelectEx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

To perform SQL SELECTs over Aerospike Predicate API, get an instance of AQLSelectEx class by supplying a schema. Schema is a simple Map<String, Map<String, Integer>>, where top-level keys are namespace[.set] and second-level keys are bin (or for MAP type bins bin.var), and leaf values are bin (or MAP bin.var) types.

As an example,

final HashMap FOO_BAR_BAZ = new HashMap() {{
        put("namespace.set0", new HashMap() {{
            put("foo", ParticleType.INTEGER);
            put("bar", ParticleType.DOUBLE);
            put("baz", ParticleType.STRING);
            put("qux", ParticleType.GEOJSON);
            put("quux", ParticleType.LIST);
            put("corge", ParticleType.MAP);
            put("corge.uier", ParticleType.INTEGER);
        }});
        put("namespace.set1", new HashMap() {{
            put("grault", ParticleType.INTEGER);
            put("garply", ParticleType.STRING);
        }});
    }};
AQLSelectEx selectEx = AQLSelectEx.forSchema(FOO_BAR_BAZ);

Bins not found in the schema are considered of type String (and you could safely omit String bins from the schema).

Now you can perform more powerful SELECTs than AQL tool, using complex expression that involve any number of bins in WHERE clause, just as you do with Predicate Filter API. Every predicate is supported. (But Filter API is supported too, using WITH syntax.)

Just see:

Statement statement = selectEx.fromString("SELECT foo,bar,baz FROM namespace.set WITH (baz='a') WHERE (foo>2 AND (bar <=3 OR foo>5) AND bar >3) OR NOT (qux WITHIN CAST('{\"type\": \"Polygon\", \"coordinates\": [0.0, 0.0],[1.0, 0.0],[1.0, 1.0],[0.0, 1.0],[0.0, 0.0]}' AS GEOJSON)");

This SELECT is fully equivalent to

Statement reference = new Statement();
reference.setSetName("set");
reference.setNamespace("namespace");
reference.setBinNames("foo", "bar", "baz");
reference.setFillter(Filter.stringEqual("baz", "a"));
reference.setPredExp(// 20 expressions in RPN
      PredExp.integerBin("foo")
    , PredExp.integerValue(2)
    , PredExp.integerGreater()
    , PredExp.integerBin("bar")
    , PredExp.integerValue(3)
    , PredExp.integerLessEq()
    , PredExp.integerBin("foo")
    , PredExp.integerValue(5)
    , PredExp.integerGreater()
    , PredExp.or(2)
    , PredExp.and(2)
    , PredExp.integerBin("bar")
    , PredExp.integerValue(3)
    , PredExp.integerGreater()
    , PredExp.and(2)
    , PredExp.geoJSONBin("qux")
    , PredExp.geoJSONValue("{\"type\": \"Polygon\", \"coordinates\": [0.0, 0.0],[1.0, 0.0],[1.0, 1.0],[0.0, 1.0],[0.0, 0.0]}")
    , PredExp.geoJSONWithin()
    , PredExp.not()
    , PredExp.or(2)
);

So, the main point of this project is code readability and maintainability. It is much easier to write and manage a couple of SQL SELECTs rather than a nearly non-comprehencible walls of PredExp calls in RPN.

For full syntax (in ANTLR4 notation) please refer to grammar file.

About

Implementation of SQL SELECT for Aerospike Predicate Filter API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages