# Index on datetime field in version \>=5

**URL:** <https://community.neo4j.com/t/index-on-datetime-field-in-version-5/81293>\
**Category:** Cypher\
**Tags:** performance, knowledge-base\
**Created:** [September 30, 2026, 12:53pm UTC](https://community.neo4j.com/t/index-on-datetime-field-in-version-5/81293 "2026-09-30T12:53:06Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![BairDev](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bairdev/32/15452_2.png) [@BairDev](https://community.neo4j.com/u/BairDev)\
**Post date:** [September 30, 2026, 12:53pm UTC](https://community.neo4j.com/t/index-on-datetime-field-in-version-5/81293/1 "2026-09-30T12:53:06Z")

</div>

There is a pretty old (2022) topic on this issue: [Best way to index a datetime field](https://community.neo4j.com/t/best-way-to-index-a-datetime-field/60232)

Considering the new index types (range index instead of BTREE index) from version \>= 5 on and the very brief documentation ([Temporal values - Cypher Manual](https://neo4j.com/docs/cypher-manual/current/values-and-types/temporal/#cypher-temporal-index)):

> All temporal types can be indexed, and thereby support exact lookups for equality predicates. Indexes for temporal instant types additionally support range lookups.

I should create a _normal_ index on a _datetime_ field (`d` on a node of type `Val`) like

`CREATE INDEX value_datetime_index FOR ( v:Val) ON (v.d);`

which will help for operations like `v.d > datetime({year: <year>, month: <month>, day: <day>})?`

We have a bunch of values on a daily basis, so roughly 365 each year and we mostly look for values an end of months or years. We should consider to use a time series DB, I know, but is a _normal_ range index suitable for this situation?

Finally: the best way to check the impact of an index by prefixing any query with `PROFILE`, right?

---

<div class="post-metadata">

**Author:** ![BairDev](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bairdev/32/15452_2.png) [@BairDev](https://community.neo4j.com/u/BairDev)\
**Post date:** [October 2, 2026, 2:40pm UTC](https://community.neo4j.com/t/index-on-datetime-field-in-version-5/81293/2 "2026-10-02T14:40:53Z")

</div>

More specifically, I have this structure `(:MeasurementSite)--(:Meter)--(:Val)` where any meter has edges to many values. When I use the following query (part): `MATCH (m:MeasurementSite)--(:Meter)--(v:Val) WHERE ID(m) = $meter AND v.d \< $end AND v.d \> $start RETURN v;`

I can see this operators in the execution plan:

`| +Filter | 3 | NOT anon_2 = anon_0 AND (cache[v.d] < $end AND cache[v.d] > $start) AND v:Val | 0 | 38 | 1037 | | 0/0 | `

`| +Expand(All) | 4 | (anon_1)-[anon_2]-(v) | 1 | 1000 | 1003 | | 0/0 | `

With an index like

`"value_date_r_index" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Val"] | ["d"] | "range-1.0"`

the execution plan remains exactly the same. What am I doing wrong or what could I improve here?

---

<div class="post-metadata">

**Author:** ![rachelwilson](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/rachelwilson/32/38680_2.png) [@rachelwilson](https://community.neo4j.com/u/rachelwilson)\
**Post date:** [October 2, 2026, 6:47pm UTC](https://community.neo4j.com/t/index-on-datetime-field-in-version-5/81293/3 "2026-10-02T18:47:39Z")

</div>

the range index is fine for this, nothing wrong with that part. the planner just wont lead with an index seek on Val when the query starts from a single MeasurementSite and expands outward, expanding is cheaper so it filters afterwards. the gotcha to check is the parameter types: if $start and $end arent actual datetime values the index cant be used for the range lookup at all. also try PROFILE with the Val pattern first, matching (v:Val) on the date range before expanding to the site, and see if the plan flips to a NodeIndexSeek.
