Search code examples
apache-ageopencypher

Storing different types in vertex properties with the same name on Apache AGE


Apache AGE allows me to store values of different types in vertex properties with the same name. For example:

Creating a vertex with pages = 10:

SELECT * FROM cypher('books', $$      
CREATE (v:Book {title: 'A book', pages: 10})
RETURN v $$) as (v agtype);
                                                v                                                 
--------------------------------------------------------------------------------------------------
 {"id": 844424930131969, "label": "Book", "properties": {"pages": 10, "title": "A book"}}::vertex
(1 row)

Creating a vertex with pages = '10':

SELECT * FROM cypher('books', $$
CREATE (v:Book {title: 'Another book', pages: '10'})
RETURN v $$) as (v agtype);
                                                    v                                                     
----------------------------------------------------------------------------------------------------------
 {"id": 844424930131970, "label": "Book", "properties": {"pages": "10", "title": "Another book"}}::vertex
(1 row)

I understand that all types return as agtype, but could this potentially cause errors in building an application?


Solution

  • Depending on what you want to return, you are returning a vertex, or one of its properties. For the types, AGE does the heavy lifting for you by asserting the types you have defined using the values you have provided.

    The agtype by itself is a custom type based of JSONB. Thus it is type-safe as it is documented in PostgreSQL

    As defined in age--x.x.x.sql:

    CREATE TYPE agtype (
      INPUT = ag_catalog.agtype_in,
      OUTPUT = ag_catalog.agtype_out,
      SEND = ag_catalog.agtype_send,
      RECEIVE = ag_catalog.agtype_recv,
      LIKE = jsonb
    );
    

    So when you are using a driver to call the PostgreSQL server running AGE. You'll be getting back JSONB like data. Upon which you can assert your preferred datatype on the values.

    As you have stated, it can become an issue due to uneven types. But, the standard type-safe way to handle any data coming from a DB would be to assert your type within your Application code. So upon running the Read operation from the database, you should make sure to set it as int in the case of your pages property value.

    OR,

    You could use functions like toInteger() & toString() within the Cypher query to assert your type before getting back the query return value.