JanusGraph / JanusGraph/janusgraph

Relation Property Index not utilized with Subgraph Strategy

Open
#4,801 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.