Cypher Sleuthing: How to Find Property Data Types in Neo4j

Photo by No Revisions on Unsplash

It’s been a while since I wrote a Cypher Sleuthing post, but I’m back with a new one! This time, I’m going to show you how to find the data types of properties in Neo4j.

I frequently want to find out the data type of a property so that I can map it in an application (in Java). I can never remember off the top of my head, and when I Google the question, the results are often outdated (here’s the answer post, but the syntax is old). So, I ended up doing a mix of searching docs and Slack messages (who has time for that?!) and trial and error. 😛

This blog post hopes to shortcut my lookup process for “future me”, as well as maybe help you out too!

Cypher Data Types

There are many data types available in Neo4j, and most of them match up to types available in other technologies. The full list is available in the Cypher documentation.

Standard, simple data types are most often used, including String, Integer, Float, Boolean, and DateTime. The mapping for Cypher to Java types is pretty straightforward, but every once in a while, I get an ugly mapping error because I didn’t verify the type conversion.

How can we verify whether a number property is an Integer or a Float? Or discern between some of the temporal/date types? Let’s see how we can do that!

Examples With Real-World Data

To test all of these queries, I’m going to use a graph based on the Northwind dataset that you can load by creating a free Neo4j Aura database, copy-pasting, and then executing the entire load script available on GitHub.

Northwind graph data model

Cypher Functions

I’ve always used and relied upon the APOC utility library for many of my Cypher needs, and this is no exception. However, Cypher adds new functions and features, and some APOC features aren’t available in all cases (sad face for Aura), so I often dig through the Cypher functions first to see what’s available.

Although Cypher can’t help us get our answer this time, there are a few Cypher functions that look deceiving. The type() and valueType() functions look like they should return data types of a property, but they do not.

The type() function returns a string representation of a relationship type, so instead of a Relationship data type, you get the text name of the relationship. The valueType() function evaluates an expression and returns a string representation of its most precise value type.

Let’s look at some examples.

//type() function
MATCH (p:Product)<-[r:ORDERS]-(o:Order)
RETURN type(r) LIMIT 1
Cypher type() function returns the text name of the relationship

So, this could be helpful if you need to print out the relationship type or use it as a dynamic value for setting other relationships, but it’s not what we’re looking for.

//valueType() function
MATCH (p:Product {productName: "Teatime Chocolate Biscuits"})
RETURN valueType(p.productName)
Cypher valueType() function returns the most precise value type of the expression

This one is even more confusing at first. It evaluates an expression and returns the data type plus the null status of the value. So, if you have a property that is a non-null Integer, it will return INTEGER NOT NULL. This might work (though a little over-engineered) if you want to get a single property’s data type, but it doesn’t work to get all the properties in a node because passing a whole node returns the complex data type NODE NOT NULL.

These Cypher options might be similar, but are more complex than the basic feature we need. APOC to the rescue!

Options With APOC

The apoc.meta.cypher.type() function is the key to getting the data type of a property. Its sister function apoc.meta.cypher.types() will return data types for all properties. Both functions return the property type(s) in string format. The functions take a single argument, which is the property/node you want to check.

//single property
MATCH (p:Product {productName: "Teatime Chocolate Biscuits"})
RETURN apoc.meta.cypher.type(p.productName);
APOC apoc.meta.cypher.type() function returns the data type of a single property
//multiple properties
MATCH (p:Product {productName: "Teatime Chocolate Biscuits"})
RETURN apoc.meta.cypher.types(p);
APOC apoc.meta.cypher.types() function returns the data types of all properties

Note that both of these functions can also handle a list as input, so we could pass in several Product nodes, and it would return the property types for each of them (example queries below). For this post, I chose to have the functions operate on a single entity just to keep the output cleaner.

//single property, multiple nodes
MATCH (p:Product)
RETURN apoc.meta.cypher.type(p.productName);

//multiple properties, multiple nodes
MATCH (p:Product)
RETURN apoc.meta.cypher.types(p);

Wrapping Up!

In today’s post, we figured out how to find the data types of properties in Neo4j. We looked at the Cypher functions type() and valueType(), which are close to what we need, but not quite. We then turned to the APOC library and found the apoc.meta.cypher.type() and apoc.meta.cypher.types() functions, which provide exactly what we were looking for.

I hope this post helps you out the next time you need to find the data type of a property in Neo4j. Happy coding!


Cypher Sleuthing: How to Find Property Data Types in Neo4j was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.