# Data type of a property

**URL:** <https://community.neo4j.com/t/data-type-of-a-property/1309>\
**Category:** Cypher\
**Tags:** cypher\
**Created:** [September 7, 2018, 8:27pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309 "2018-09-07T20:27:07Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike\_r\_black](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/mike_r_black/32/30089_2.png) [@mike\_r\_black](https://community.neo4j.com/u/mike_r_black)\
**Post date:** [September 7, 2018, 8:27pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/1 "2018-09-07T20:27:08Z")

</div>

In Cypher how can I check the data type of a property?

Once a property is used for one data type, are all properties for that node label that same property? I'm assuming no. So if I have a node label `:testnode` and I have a property of `mystery`. I could mix-match putting numbers, strings, dates, etc... in the nodes. Obviously a data quality nightmare but that leads me back to my first question. I'd like to be able to query my nodes and look for data quality issues.

---

<div class="post-metadata">

**Author:** ![david\_allen](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/david_allen/32/13090_2.png) [@david\_allen](https://community.neo4j.com/u/david_allen)\
**Post date:** [September 7, 2018, 8:32pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/2 "2018-09-07T20:32:46Z")

</div>

Cypher properties always have a type, but Neo4j doesn't constrain their type. That is to say that if you have a node property called `mystery`, it's possible to make it sometimes a string, sometimes an integer.

For example, this is OK:

```auto
CREATE (:testnode { mystery: 1 });
CREATE (:testnode { mystery: "Hello" });

```

A way that you can profile looking for data quality issues is by checking types like this:

```auto
MATCH (t:testnode)
WHERE t.mystery = toString(t.mystery)
RETURN count(t);

```

That will tell you how many strings there are. If the property were an int, it wouldn't match. You could do a similar things with other types too, to build up a table of how many instances were which type for an attribute.

**UPDATE July 2023**

As of Neo4j 5.9 there are now property type constraints and property type predicates are coming.

> **[Examples - Cypher Manual](https://neo4j.com/docs/cypher-manual/current/constraints/examples/#constraints-examples-node-uniqueness)**
>
> Examples of how to manage constraints used for ensuring data integrity.

**UPDATE August 2020**

In recent versions of APOC, there is `CALL apoc.meta.nodeTypeProperties()` and `CALL apoc.meta.relTypeProperties()` which samples the database and outputs schema for all labels & rel types. This is a great way to detect (for example) if any property in the database ever has more than one distinct type. So in the example I gave above with the "mystery" property, the results of those procedures would report that the "mystery" property is of type ["String", "Long"]

---

<div class="post-metadata">

**Author:** ![mike\_r\_black](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/mike_r_black/32/30089_2.png) [@mike\_r\_black](https://community.neo4j.com/u/mike_r_black)\
**Post date:** [September 7, 2018, 8:48pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/3 "2018-09-07T20:48:26Z")

</div>

Thanks!

I think you may have given me an idea for a way I could contribute to the APOC library. Have a function like DataType() that would go through a series of case statements testing each data type and return a string value of the data type that it was determined to be.

---

<div class="post-metadata">

**Author:** ![Benoit](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/benoit/32/551_2.png) [@Benoit](https://community.neo4j.com/u/Benoit)\
**Post date:** [September 8, 2018, 6:56am UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/4 "2018-09-08T06:56:11Z")

</div>

Hi Mike,

In fact it already exists, take a look at `apoc.meta.type` function.

Example :

```
WITH [true, 42, 'foo', 1.2] AS data
UNWIND data as value
RETURN apoc.meta.type(value)

```

Result is :

```
"BOOLEAN"
"INTEGER"
"STRING"
"FLOAT" 

```

Cheers

---

<div class="post-metadata">

**Author:** ![david\_allen](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/david_allen/32/13090_2.png) [@david\_allen](https://community.neo4j.com/u/david_allen)\
**Post date:** [September 8, 2018, 4:49pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/5 "2018-09-08T16:49:51Z")

</div>

Benoit's got a good idea -- thing is I would just caution you that there's a way of telling the type of an individual property value, but that's not the same thing as a property having a type -- they don't have types, or at least they can vary.

Reason I bring this up is that you need to do some kind of sampling, like for example `MATCH (n:Node) return n.mystery limit 100` or `MATCH (n:Node) where id(n) % 3 = 0 return n.mystery limit 100`. Only if the types of all of the sample agree is it probably safe to assume that's the type of the property.

---

<div class="post-metadata">

**Author:** ![pradeep.ponduri](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pradeep.ponduri/32/768_2.png) [@pradeep.ponduri](https://community.neo4j.com/u/pradeep.ponduri)\
**Post date:** [October 12, 2018, 4:07pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/6 "2018-10-12T16:07:06Z")

</div>

Once a property is set as INT, how to make sure new values for that property too are INT.

Example:  
I created a node with age as property and type casted it to INT.  
When am creating nodes using load csv or jdbc, this age property is loaded as string not INT.  
Do I need to typecast everytime i load?

---

<div class="post-metadata">

**Author:** ![elaine\_rosenber](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/elaine_rosenber/32/27409_2.png) [@elaine\_rosenber](https://community.neo4j.com/u/elaine_rosenber)\
**Post date:** [October 12, 2018, 4:25pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/7 "2018-10-12T16:25:40Z")

</div>

Properties do not have types. When you load the data, you must convert the data to the type that you want for that property.

---

<div class="post-metadata">

**Author:** ![geotheory1](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/geotheory1/32/3786_2.png) [@geotheory1](https://community.neo4j.com/u/geotheory1)\
**Post date:** [March 20, 2019, 10:03am UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/8 "2019-03-20T10:03:52Z")

</div>

Is this always true? I seem to be ingesting CSV files using `neo4j-admin import` with arguments like `--nodes "import/nodes_header.csv,import/nodes.csv"` where nodes\_header.csv specifies data types e.g. `value:int` and `live:Boolean`..

---

<div class="post-metadata">

**Author:** ![elaine\_rosenber](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/elaine_rosenber/32/27409_2.png) [@elaine\_rosenber](https://community.neo4j.com/u/elaine_rosenber)\
**Post date:** [March 20, 2019, 12:10pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/9 "2019-03-20T12:10:25Z")

</div>

Properties themselves do not have types, but the values they hold do. On import, numeric values, booleans, strings are all stored differently for a property which is why they need to be imported as typed data. However, you can have a property, X which could be assigned a string value or a numeric value. We don't enforce typing for a property. Of course, it would not make sense to assign a property different type values in your graph.

Elaine

---

<div class="post-metadata">

**Author:** ![elucian](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/elucian/32/13296_2.png) [@elucian](https://community.neo4j.com/u/elucian)\
**Post date:** [August 17, 2020, 5:46pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/10 "2020-08-17T17:46:30Z")

</div>

is there any way to constrain node properties to type? like some kind of schema. Would save a lot of boilerplate code, increase readability of cypher queries, and give us a safer database.

either that or some kind of database action that validates type before the node is comitted (which we could define the rules for ourselves as a hacky solution)

---

<div class="post-metadata">

**Author:** ![tony.chiboucas](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/tony.chiboucas/32/5980_2.png) [@tony.chiboucas](https://community.neo4j.com/u/tony.chiboucas)\
**Post date:** [August 17, 2020, 7:20pm UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/11 "2020-08-17T19:20:30Z")

</div>

The syntax for creating constraints was designed with future extensibility in mind. With a growing interest in more specific and rigid constraints, it _might_ be worth revisiting the Cypher constraint parser to add more flexible syntax.

Existing constraint syntax _implies_ `ASSERT xxx` is a parsed result expecting `xxx` to be a boolean result. If it was, we could do something like the following:

```auto
CREATE CONSTRAINT ON (book:Book) ASSERT apoc.meta.type(book.id) = "INTEGER";

```

Currently supported constraints are _only_ those documented in [5.4 Constraints](https://neo4j.com/docs/cypher-manual/current/administration/constraints/):

- `ASSERT (node.property [, ...]) IS UNIQUE`
- `ASSERT (node.property [, ...]) EXISTS`
- `ASSERT (node.property [, ...]) IS NODE KEY`

These constraints are a boon to defining production data, but have not yet been expanded beyond the initial definition:

> <https://github.com/neo4j/neo4j/commit/49ae8fcb64a3470421736609d54cbf0104a66a8a#diff-1a7d8a35fc7dd8b249101493aae7aeffR29>
>
> o Create contraint syntax, for example:
> CREATE CONSTRAINT ON (foo:Foo) ASSERT …foo.name IS UNIQUE
> o Drop constraint syntax, for example:
> DROP CONSTRAINT ON (foo:Foo) ASSERT foo.name IS UNIQUE
> o Doesn't actually do anything, just able to parse it.

So, if anyone out there is looking for a way to contribute to Neo4j in a big way, this would be a good one. (Might be me, once I finish my current efforts)

---

<div class="post-metadata">

**Author:** ![zzfima](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/zzfima/32/28761_2.png) [@zzfima](https://community.neo4j.com/u/zzfima)\
**Post date:** [May 27, 2023, 9:53am UTC](https://community.neo4j.com/t/data-type-of-a-property/1309/12 "2023-05-27T09:53:29Z")

</div>

In course neo4j there " [Viewing Property Types Stored in the Graph](https://graphacademy.neo4j.com/courses/importing-data/3-refactoring-imported-data/1-transform-strings/)".

Explains:  
\*\*\* types for the node properties in the graph using _apoc.meta.nodeTypeProperties()_  
\*\*\* investigation of types for relationship properties using _apoc.meta.relTypeProperties()_
