Ostico / PhpOrient

PhpOrient - Official Php driver based on the binary protocol of OrientDB.
Other
68 stars 37 forks source link

Losing edges when manually removing them from OData #62

Open andreyvk opened 8 years ago

andreyvk commented 8 years ago

Hi @Ostico,

I need your expertise here big time. It's not a bug, but rather a huge inconvenience. Here's the explanation:

  1. When you pull a record from database, by default it pulls edges along
  2. Then get OData, remove edges manually (e.g. unset($odata["in_edge"]) ) and set OData back to the record.
  3. Store the record. The edge, that we manually removed, is lost!

Take a look at this gist for more details.

The problem

We will have certain records in database, which will be connected to thousands upon thousands of other records through edges. So, in order to update that sort of record we need to get the whole data (which is large, including edges), update a few attributes and then store the record. This is a huge overhead.

Solution?

I know it's possible to update the record using UPDATE statement, but might be near to impossible sometimes. recordUpdate() is a much better way.

  1. Is there any way to update only non-edge data using recordUpdate() and not lost edges?
  2. Is this binary protocol limitation. If yes, then will the next version of binary protocol have this problem as well?
  3. Should I rather contact OrientDB team for this problem or is there another solution, besides using UPDATE statements?

Counting on your soonest reply. Thanks!

Ostico commented 8 years ago

Hi @andreyvk ,

i understand your issue. I tried some ways.

Unfortunately the CRUD methods on the binary protocol does not permit in any way to update only a single field of the record.

I wondered that on the HTTP protocol instead, there is a partial option: http://orientdb.com/docs/2.0/orientdb.wiki/OrientDB-REST.html#put---document

So, i read the OrientDB source code here: https://github.com/orientechnologies/orientdb/blob/master/server/src/main/java/com/orientechnologies/orient/server/network/protocol/binary/ONetworkProtocolBinary.java#L1540

following the code until i reached this: https://github.com/orientechnologies/orientdb/blob/master/server/src/main/java/com/orientechnologies/orient/server/network/protocol/binary/OBinaryNetworkProtocolAbstract.java#L161

This is an atomic update and no merge strategies are implemented on that.

The HTTP protocol instead implements a data merge algorithm: https://github.com/orientechnologies/orientdb/blob/master/server/src/main/java/com/orientechnologies/orient/server/network/protocol/http/command/put/OServerCommandPutDocument.java#L89

It is implemented server side, so no data transfer from and versus the client is needed.

So i think ( at least to my knowledge ) there is no way to avoid the data transfer overhead.

BTW, i not talked with the OrientDB team, so feel free to ask them for a solution.

andreyvk commented 8 years ago

@Ostico thanks for your update on this. It's quite an inconvenience that binary protocol does atomic updates only. So I guess at this point we will have to improvise with UPDATE statements. Plz, keep this issue open for a while, so I can contact OrientDB guys and see what they can suggest.

Ostico commented 8 years ago

Of course