JanusGraph / JanusGraph/janusgraph
Relation Property Index not utilized with Subgraph Strategy
- Dominant language
- Java
- Stars
- 5.8k
- Forks
- 1.2k
- Avg merge
- 13h 53m
- Merged PRs (30d)
- 6
Description
**Relation Property Index not utilized with Subgraph Strategy with some of the steps**
Subgraph Strategy is often used with condition that apply to the metadata, like a time machine described in JanusGraph documentation. It is adding condition to the "vertexProperties" segment, and that works beautifully simplifying entire Gremlin statement, however required syntax is very strict, and some steps are not working in that obvious way.
**Steps to reproduce using popular samples from JanusGraph documentation: **
```
graph = JanusGraphFactory.open("inmemory")
mgmt = graph.openManagement()
timestamp = mgmt.makePropertyKey("timestamp").dataType(Integer.class).make()
amount = mgmt.makePropertyKey("amount").dataType(Integer.class).cardinality(Cardinality.LIST).make()
mgmt.buildPropertyIndex(amount, 'amountByTime', Order.desc, timestamp)
mgmt.commit()
bob = graph.addVertex()
bob.property("amount", 100, "timestamp", 1600000000)
bob.property("amount", 200, "timestamp", 1500000000)
bob.property("amount", -150, "timestamp", 1550000000)
graph.tx().commit()
g = graph.traversal()
```
- standard way of utilizing secondary index for property "amount" having metadata "timestamp", by index 'amountByTime',
where profile is reporting `\_query=2053:amountByTime:SliceQuery[0x90E0,0x90E0FF2697D0FF)`
`g.V(bob).properties("amount").has("timestamp", P.gt(1500000000)).profile()` // INDEX
- Subgraph Strategy utilizing secondary index for property "amount" having metadata "timestamp", by index 'amountByTime',
where profile is reporting `\_query=2053:amountByTime:SliceQuery[0x90E0,0x90E0FF2697D0FF)`
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).properties("amount").profile() ` // INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).values("amount").profile()` // INDEX
- No index when using `.is()` step, where conditions by strategy are actually added by `OrStep([[ClassFilterStep(VertexProperty)]()`:
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).has("amount",is(eq(150))).profile()` // NO INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).properties("amount").hasValue(eq(150)).profile()` // INDEX
- No index when using `.coalesce()` step, strategy conditions applied to the VertexProperty step:
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).coalesce( __.properties("amount"), constant("null")).profile()` // NO INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).coalesce( __.values("amount"), constant("null")).profile()` // NO INDEX
- No Index when using `.project()` step, strategy conditions applied to the VertexProperty step:
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).project("val").by(__.properties("amount").value()).profile()` // NO INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).project("val").by(__.values("amount")).profile()` // NO INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).properties("amount").profile()` // INDEX
- No index when using groupCount():
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).groupCount().by(__.values("amount")).profile()` // NO INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).values("amount").profile()` // INDEX
- No index when using `select()` step:
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).as("v").values("amount").profile()` // INDEX
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).as("v").select("v").values("amount").profile()` // NO INDEX
- No index when using `choose()` step:
`g.withStrategies(SubgraphStrategy.build().vertexProperties(__.has("timestamp", P.gt(1500000000))).create()).V(bob).choose(__.properties("amount"), constant("a"), constant("b")).profile()` NO INDEX
... and probably few more like that, indicating some kind of inconsistency of the pre- and post- processing the query.
Contributor guide
Research direction
Start with the SubgraphStrategy entry point and reproduce the listed traversals using the JanusGraph documentation sample and profile output. Compare the indexed and non-indexed forms across is(), coalesce(), project(), groupCount(), select(), and choose(); done means the affected forms consistently use the relation property index where applicable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100