Ostico / PhpOrient

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

Query always returns data as array? #21

Open odiel opened 9 years ago

odiel commented 9 years ago

I'm creating records that contains an embed JSON object, but when queering them PhpOrient is always returning them as an array instead of an object, is there a way to let the library know about this, or it is something not implemented yet?

andreyvk commented 9 years ago

@Ostico knows better, but in my experience anything representing a record (or embedded record for this matter) is represented as an associative array in this library.

It might be useful to have:

  1. Local setting when querying for data (e.g. $client->query("...", ["dataFormat"=>"object"]) )
  2. Global setting on the PhpOrient instance (e.g. $client->configure(["dataFormat"=>"object"]) )

For now, however, you can just explicitly convert arrays to objects with

$obj = (object) $arr;
odiel commented 9 years ago

I see, well from my understanding by using other libraries for OrientDB, a record represents an object in the schema, and a property can hold any type of the supported values: string, int, embed array, embed objects.

If the library converts everything to object or array, then there is no way to know from the application which is the actual type of value coming from the DB.

andreyvk commented 9 years ago

Could you provide an example of how you store your embedded data? Are you using schema or is it a schemaless embedded attribute?

odiel commented 9 years ago

I'm using a mix of both, I have a base Schema class with few properties, the created documents must have those few properties plus any other json friendly type of property.

Example:

{"id":"1234", "type":"Event", "details":[1, 2, 3, 5, 6, 7], "properties":{"property1":"value1", "property2":[4,5,6], "property3":{"subProperty":"valueForSubProperty"}}}

This is how I'm performing the insert:

$query = 'INSERT INTO Event CONTENT '.json_encode($event);
$orientDBClient->command($query);
Ostico commented 9 years ago

Hi @odiel , I'm happy to improve if possible.

What kind of output from your json you would expect?

The arrays with numeric indexing should be simple arrays and the associative arrays should be objects?

There are some issues with this approach, one of these are in this example:

$x = array ( 0,1,2,3,4 );
print_r(json_encode($x));
// prints: 
// [0,1,2,3,4]

unset ( $x[1] );
print_r( json_encode($x) );

//prints:
// {"0":0,"2":2,"3":3,"4":4}

Php json_encode treats the array that lacks numeric indexes as an object.

In this way this object is no more readable because you can't access numeric properties:

var_export( json_decode( json_encode( $x ) ) );
stdClass::__set_state(array(
   '0' => 0,
   '2' => 2,
   '3' => 3,
   '4' => 4,
))

By the way i think i can improve by checking the result from the query, orient tells me if the field is a list or an hashmap/dictionary/associative array.

Let me know if this is what you expect.

odiel commented 9 years ago

Hi @Ostico

I was expecting to have the record as an Object, since it represents a document, and the properties of the document as the type of data they are defined in OrientDB. Totally agree with your explanation about the encoding of arrays. As you said checking the type of field coming from Orient is your best bet to generate the record.