orientechnologies / orientdb-labs

OrientDB Labs hosts last development version of OrientDB.
Apache License 2.0
17 stars 3 forks source link

[OEP 5] Query and ResultSet API #5

Closed tglman closed 6 years ago

tglman commented 8 years ago

Summary: Simple query API that support streaming results and complex results like graph portions, as well as simple record fetching.

Goals:

Non-Goals:

Motivation:

Description: new database api for direct query without wrapping objects:

new database api for prepare :

Prepered execution:

ResultSet access:

For OResult value access will follow, ODocument/OVertex/OEdge api, OResult can not be a record, so it will have api for check this and access to the relative record in case

As well the OResult have to allow traversal of projected relations, following the base api.

early stage examples: https://gist.github.com/tglman/c3a3ceb6a9891ceae3eb4701a69ba0e3

Alternatives:

None known yet

Risks and assumptions:

Braking api, we need to include a compatibility layer with the past for early versions.

Impact matrix

luigidellaquila commented 8 years ago

+1 to the API.

About OResult hierarchy, I'm not so convinced, what's the advantage compared to having ODocument? The overhead on the server can be completely avoided (no instantiation of ODocument, just write on the stream) and on the client it should not be a problem...

luigidellaquila commented 8 years ago

To be more explicit, are you proposing the following?

tglman commented 8 years ago

@luigidellaquila

yes, I don't wont the result to be an Identifiable, and as well keep the cost of all the document tracking structures, not needed for just get a value

exactly OResult is OElement + Set<OResult> getVertices(Direction direction,String label) for projected relations, we could move some of the api on the top structure maybe.

probably we will need something like geEdges as well

luigidellaquila commented 8 years ago

So it's mainly for a performance concern, and only on the client side...?

tglman commented 8 years ago

Not to be an Identifiable is because in that case we need to provide an id everytime that is confusing for the projection case (see the today #-2:n), in embedded as well a projection query should not return documents, for both consistency and performance reasons

lvca commented 8 years ago

@tglman could you write an example of executing a query that return 1 record and update it?

luigidellaquila commented 8 years ago

I think the idea is this (@tglman correct me if I'm wrong)

db.query("select form V")
  .stream()
  .map(r -> r.asDocument())
  .foreach(doc->{
    doc.setProperty("foo", "bar");
    db.save(doc);
  });
lvca commented 8 years ago

The fact that OrientDB v3 will require Java8, it doesn't mean that users are forced to use the lambda syntax. And without using streams it should be:

OResultSet resultset = db.query("select form V");
for( OResult r : resultset ){
  ODocument doc = r.asDocument();
  doc.setProperty("foo", "bar");
  db.save(doc);
};

While I see the benefits of having a resultset instead if a List, I don't see the need to have an OResult and then retrieve the document with.asDocument(). It's a complication of current API. If the only reason is to avoid a projection is saved back, just don't allow to save any document with a RID as projection.

luigidellaquila commented 8 years ago

Yep, it was my point as well. @tglman point is that an OResult can be a projection (without an OIdentity) and we can avoid at compile time to let users save it...

tglman commented 8 years ago

well, the point is that a result set is not needed to be a document, actually there are plenty of cases where is not, like: projections, aggregation functions, nested projection, match statement with multiple returns, command operation returns, batch scripts returns, force everything to be a document it seams to be an overkill for just the case where you extract records.

as well there are case where the behaviour can be confusing like: select *,"name" as name from V the result have to have the field name and have to have a valid identity, but you are not allowed to save it, the 'asDocument()' api in this case will give you out the document without the filed name, ready to be manipulated.

As last detail, the implamentation of a OResult, it's not going to be a document in most of the cases, without overhead like tracking ecc. in some cases will be more similar to a list of arrays.

luigidellaquila commented 8 years ago

For the case of SELECT *, foo FROM..., imho the result should not have an identity, and all the fields of @this should be at the same level of foo, so it could be considered as a normal projection

lvca commented 8 years ago

I agree that in the @luigidellaquila example, it shouldn't have an identity. About all the things you don't need of ODocument I agree: we could keep super light result sets in RAM and I can see the benefit of it. So in the case of select from V ODocument instances are returned, right? Or do you create ODocument at the fly at asDocument() call?

tglman commented 8 years ago

@lvca not sure yet if the select from V create the ODocument directly or later, i would say as first implementation directly, but could be optimized in the long run. consider as well that we could provide Iterable<ODocument> db.query("select from v ").asDocuments() or something like this.

tglman commented 8 years ago

by the way OResult should not have any public 'set' methods, speaking about hierarchies OResult would actually fit well on top of OElement for the method that it provide.

luigidellaquila commented 7 years ago

Little addition to the ResultSet API:

class ResultSet{
...
  Optional<OExecutionPlan> getExecutionPlan();

  Map<String, Object> getQueryStats();

}
luigidellaquila commented 6 years ago

Implemented, closing