https://github.com/datagrids/spec/wiki/Proposed-featuresGoing through this list....Seems like at least a simple Query API could be added.Some subset that Infinispan already offers would be a great start.
Also not 100% comfortable with Operations Mode. Seems we would/could/should tread lightly since these are more implementation details.Not everyone has the same ideas of how to create elastic instances and/or what should happen if you add nodes dynamically.
I need to bone up on MapReduce. I think I have some comments there, but at the risk of sounding like a complete rube. I will hold off.I really like the concepts of the Group API.Where are the JSR 347 discussions happening... there does not seem to be much on the group yet.'
Of course I found some small errors, JCache put does not return a value, so it could be async (it returns a void).
Highlights:
- minimal typing
- no joins
- provides for per-statement consistency level
I'm on the fence about whether this is in scope though.
Another thing that sticks out to me is balancing eventually
consistency with transaction isolation. Transaction recovery becomes
extremely complicated with idempotent storage systems when a write may
or may not have been received (or received partially, but not by
enough hosts to satisfy the consistency level). It is going to be very
difficult to decide what guarantees to provide and when to provide
them.
Regards,
-Nate
Ideally I would like to see this have some more moving parts than a
'key/value' store, but I understand that any idiomatic approach beyond
that gets significantly more difficult given the number of vendors.
Just to be clear - range scanning for arbitrary keys in big systems is
for suckers, IMO. Too much depends on the cluster's partitioning
mechanics. If supported at all, it should be with a big, fat "do this
only in low-priority background jobs" warning sticker.
That's a good point. A lot of this will depend on the dimension of the
map as a query API won't make much sense for simple get/put
operations. Querying would be helpful to "slice" the nested values of
the map to limit the result set size.
Ideally I would like to see this have some more moving parts than a
'key/value' store, but I understand that any idiomatic approach beyond
that gets significantly more difficult given the number of vendors.
Just to be clear - range scanning for arbitrary keys in big systems is
for suckers, IMO. Too much depends on the cluster's partitioning
mechanics. If supported at all, it should be with a big, fat "do this
only in low-priority background jobs" warning sticker.
// Get the Datastore Service
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
// The Query interface assembles a query
Query q = new Query("Person");
q.addFilter("lastName", Query.FilterOperator.EQUAL, lastNameParam);
q.addFilter("height", Query.FilterOperator.LESS_THAN, maxHeightParam);
// PreparedQuery contains the methods for fetching query results
// from the datastore
PreparedQuery pq = datastore.prepare(q);
for (Entity result : pq.asIterable()) {
String firstName = (String) result.getProperty("firstName");
String lastName = (String) result.getProperty("lastName");
Long height = (Long) result.getProperty("height");
System.out.println(lastName + " " + firstName + ", " + height.toString() + " inches tall");
}
Okay. Two thoughts:First: let's not think "infinispan" or any other specific product *yet* - I'm trying to keep in mind how features from the JSR would map to existing products in the space, but I'm also not trying to say "let's use X from Y" if I can help it. I've been borrowing Infinispan's annotations mostly because the wiki points to them.
Second: What exactly would a query *return*?
Given that we're more or less using a map abstraction, we have two sets to return values from, a keyset and a valueset; however, other query languages can return data that's *not* part of the original query set. Are we suggesting that we run selection criteria? If so, on the key set, or the value set?
How do we do so efficiently?
I guess my thought was that a query "API" could be bundled in as a workable abstraction *on top of* the map/reduce API, so you'd have the appearance of a query API without having the performance-crushing implications of a direct query mechanism.
Further, making optional the map-reduce component would be handy - a
couple different folks have secondary indexing capability and can do
queries like this on-line. Maybe allowing it to be applied at an
arbitrary phase of the query to support pre-filtering via M/R and/or
projections on large results (or just querying directly)? Extending
Rick's example:
q.addReducer("lastName", Query.FilterOperator.EQUAL, Reducer.BEFORE,
lastNameParam);
More thinking out loud here. I could see that getting clunky.
On Wed, Sep 28, 2011 at 4:51 PM, Rick Hightower
The problem with swinging for the fences is the risk of failure is too high.First version can have a simple query (I think).
Others will build frameworks and solutions on top (maybe do some stuff we did not think of... maybe do some stuff that sucks... maybe do some very cool stuff).With 20/20 clarity we can see what works and prune what does not work and enhance what does.
Comments inline:On 27 September 2011 23:14, Rick Hightower <richardh...@gmail.com> wrote:https://github.com/datagrids/spec/wiki/Proposed-featuresGoing through this list....Seems like at least a simple Query API could be added.Some subset that Infinispan already offers would be a great start.We could start discussing it, but what I find hard is that we need a query language suited for data grids in the first place. I don't see any existing work as a "good fit". SQL is too relational, JP-QL also too relational. And coming up with a query language is definitely out of the scope of this JSR. Perhaps some rudimentary filters may work. Infinispan's impl is far too closely coupled with Lucene's query POJOs IMO, to become a standard.
--
You received this message because you are subscribed to the Google Groups "JSR 347 discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsr347+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
List<Employee> employees = repo.query(
and(startsWith("firstName", "Bob"), eq("lastName", "Smith"), between("salary", 190_000, 200_000)));
int sum = repo.query(eq("lastName", "Smith")).stream().filter(emp -> emp.getSalary()>50_000)
.mapToInt(b -> b.getSalary())
.sum();
List<User> results = userRepo.query ( eq ( EMAIL, "rick.hi...@foo.com") );
static Group and(Criteria... expressions) static Criterion between(java.lang.Class clazz, java.lang.Object name, java.lang.String svalue, java.lang.String svalue2) static Criterion between(java.lang.Object name, java.lang.Object value, java.lang.Object value2) static Criterion between(java.lang.Object name, java.lang.String svalue, java.lang.String svalue2) static Criterion contains(java.lang.Object name, java.lang.Object value) static Criterion empty(java.lang.Object name) static Criterion endsWith(java.lang.Object name, java.lang.Object value) static Criterion eq(java.lang.Object name, java.lang.Object value) static Criterion eqNested(java.lang.Object value, java.lang.Object... path) static Criterion gt(java.lang.Object name, java.lang.Object value) static Criterion gt(java.lang.Object name, java.lang.String svalue) static Criterion gte(java.lang.Object name, java.lang.Object value) static Criterion implementsInterface(java.lang.Class<?> cls) static Criterion in(java.lang.Object name, java.lang.Object... values) static Criterion instanceOf(java.lang.Class<?> cls) static Criterion isNull(java.lang.Object name) static Criterion lt(java.lang.Object name, java.lang.Object value) static Criterion lte(java.lang.Object name, java.lang.Object value) static Not not(Criteria expression) static Criterion notContains(java.lang.Object name, java.lang.Object value) static Criterion notEmpty(java.lang.Object name) static Criterion notEq(java.lang.Object name, java.lang.Object value) static Criterion notIn(java.lang.Object name, java.lang.Object... values) static Criterion notNull(java.lang.Object name) static Group or(Criteria... expressions) static Criterion startsWith(java.lang.Object name, java.lang.Object value) static Criterion typeOf(java.lang.String className)
rick = (User) //expectOne is not generic userRepo.results ( eq ( EMAIL, "rick.hi...@foo.com" ) ) .expectOne ().firstItem ();
public interface ResultSet<T> extends Iterable<T> { ResultSet expectOne(); <EXPECT> ResultSet <EXPECT> expectOne(Class<EXPECT> clz); ResultSet expectMany(); ResultSet expectNone(); ResultSet expectOneOrMany(); ResultSet removeDuplication(); ResultSet sort(Sort sort); Collection<T> filter(Criteria criteria); ResultSet<List<Map<String, Object>>> select(Selector... selectors); int[] selectInts(Selector selector); float[] selectFloats(Selector selector); short[] selectShorts(Selector selector); double[] selectDoubles(Selector selector); byte[] selectBytes(Selector selector); char[] selectChars(Selector selector); Object[] selectObjects(Selector selector); <OBJ> OBJ[] selectObjects(Class<OBJ> cls, Selector selector); <OBJ> ResultSet<OBJ> selectObjectsAsResultSet(Class<OBJ> cls, Selector selector); Collection<T> asCollection(); String asJSONString(); List<Map<String, Object>> asListOfMaps(); List<T> asList(); Set<T> asSet(); List<PlanStep> queryPlan(); T firstItem(); Map<String, Object> firstMap(); String firstJSON(); int firstInt(Selector selector); float firstFloat(Selector selector); short firstShort(Selector selector); double firstDouble(Selector selector); byte firstByte(Selector selector); char firstChar(Selector selector); Object firstObject(Selector selector); <OBJ> OBJ firstObject(Class<OBJ> cls, Selector selector); List<T> paginate(int start, int size); List<Map<String, Object>> paginateMaps(int start, int size); String paginateJSON(int start, int size); //Size can vary if you allow duplication. //The size can change after removeDuplication. int size(); }
Repo<Integer,Employee> employeeRepo; /** It builds indexes on properties. */ employeeRepo = Repos.builder() .primaryKey("id") .searchIndex("department.name") .searchIndex("salary") .build(int.class, Employee.class).init(employees);
List<Employee> results = employeeRepo.query(eq("department.name", "HR")); /* Verify. */ Int.equalsOrDie(4, results.size()); Str.equalsOrDie("HR", results.get(0).getDepartment().getName());
list = employeeMapRepo.query( selects( selectAsTemplate("fullName", "{{firstName}} {{lastName}}", template), selectAs("contactInfo.phoneNumbers[0]", "ph"), selectAsTemplate("pay", "{{pay(salary)}}", template), selectAsTemplate("id", "{{DecryptionService.decrypt(id)}}", template) ) );
One should be able to plug in Guava, Concurrent Trees or Trove if one desires to do so.
Boon's data repo makes doing index based queries on collections a lot easier.
It provides a simplified API for doing so. It allows linear search for a sense of completion but I recommend using it primarily for using indexes and then using the streaming API for the rest (for type safety and speed).
You can use a wrapper class to wrap a collection into a indexed collection.
So.... anyway... this is not a complete thought or clear set of ideas of direction but I mere putting gas on the flames.
107 delivered a lot of what was in the original 347 charter.
I think query (some simplified version) should be on the table.
I actually really like the Hazelcast interfaces for a lot of this so.... maybe we can start there...
https://github.com/datagrids/spec/wiki/Proposed-featuresGoing through this list....Seems like at least a simple Query API could be added.Some subset that Infinispan already offers would be a great start.
Also not 100% comfortable with Operations Mode. Seems we would/could/should tread lightly since these are more implementation details.Not everyone has the same ideas of how to create elastic instances and/or what should happen if you add nodes dynamically.
I need to bone up on MapReduce. I think I have some comments there, but at the risk of sounding like a complete rube. I will hold off.I really like the concepts of the Group API.Where are the JSR 347 discussions happening... there does not seem to be much on the group yet.'