-
Notifications
You must be signed in to change notification settings - Fork 861
[TINKERPOP-3261] Enable multiple labels on vertex with configurable label cardinality #3483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
da4ec2a
be3e714
f4180a2
be5072e
6a3c91e
99f496a
687878f
dfc1827
561723f
d6c57e2
1310986
f1e678b
102938e
b88f22e
43e0336
9ea3df1
2958a30
278b64b
d272791
0b33a8f
2eefc22
083c9a6
9db5db5
7855ccf
db79ef9
d036429
941dd3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -587,6 +587,84 @@ See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/j | |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java[source (start)], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#addvertex-step[reference] | ||
|
|
||
| === addLabel() | ||
|
|
||
| *Description:* Adds one or more labels to an element. | ||
|
|
||
| *Syntax:* `addLabel(String label, String... moreLabels)` | `addLabel(Traversal<?, ?> labelTraversal, Traversal<?, ?>... moreLabelTraversals)` | ||
|
|
||
| [width="100%",options="header"] | ||
| |========================================================= | ||
| |Start Step |Mid Step |Modulated |Domain |Range | ||
| |N |Y |N |`Element` |`Element` | ||
| |========================================================= | ||
|
|
||
| *Arguments:* | ||
|
|
||
| * `label` - The label to add. | ||
| * `moreLabels` - Additional labels to add. | ||
| * `labelTraversal` - The first (or only) traversal that produces a label to add. | ||
| * `moreLabelTraversals` - Additional label-producing traversals (may be empty for single-traversal behavior). | ||
|
|
||
| *Considerations:* | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"supports mutation"? First, that sounds a bit odd...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've reworded this for clarity, but yes singlelabel does imply immutability, because there is no atomic operation to replace labels, and there labels cannot be added or removed without violating the cardinality. This also keeps |
||
|
|
||
| Label add and remove operations require a `LabelCardinality` that permits changing the set of labels on an element | ||
| (`ONE_OR_MORE` or `ZERO_OR_MORE`). When `LabelCardinality` is `ONE`, the vertex's label is fixed at creation and | ||
| cannot be added to or removed. | ||
| Adding a label that already exists on the element is a no-op. The step returns the element (sideEffect semantics). | ||
| Each traversal argument is iterated for a single result only. If exactly one traversal is provided and it produces | ||
| a `Collection<String>`, the collection will be automatically unfolded into the set of labels added; if more than one | ||
| traversal is provided, each must resolve to a single `String` label. | ||
|
|
||
| *Exceptions* | ||
|
|
||
| * If the graph's `LabelCardinality` does not permit label modification, an `IllegalStateException` will be thrown. | ||
| * If any label argument is null or empty, an `IllegalArgumentException` will be thrown. | ||
| * If more than one traversal is provided and any of them produces a `Collection`, an `IllegalArgumentException` will | ||
| be thrown. | ||
|
|
||
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddLabelStep.java[source], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#addlabel-step[reference] | ||
|
|
||
| === dropLabel() | ||
|
|
||
| *Description:* Removes one or more specific labels from an element, or removes all labels. | ||
|
|
||
| *Syntax:* `dropLabel(String label, String... moreLabels)` | `dropLabel(Traversal<?, String> labelTraversal, Traversal<?, String>... moreLabelTraversals)` | `dropLabels()` | ||
|
|
||
| [width="100%",options="header"] | ||
| |========================================================= | ||
| |Start Step |Mid Step |Modulated |Domain |Range | ||
| |N |Y |N |`Element` |`Element` | ||
| |========================================================= | ||
|
|
||
| *Arguments:* | ||
|
|
||
| * `label` - The label to remove. | ||
| * `moreLabels` - Additional labels to remove. | ||
| * `labelTraversal` - The first (or only) traversal that produces a label to remove. | ||
| * `moreLabelTraversals` - Additional label-producing traversals (may be empty for single-traversal behavior). | ||
|
|
||
| *Considerations:* | ||
|
|
||
| Label add and remove operations require a `LabelCardinality` that permits changing the set of labels on an element | ||
| (`ONE_OR_MORE` or `ZERO_OR_MORE`). Dropping a label that does not exist | ||
| on the element is a no-op. `dropLabels()` removes all labels (only valid with `ZERO_OR_MORE`). The step returns the | ||
| element (sideEffect semantics). | ||
| Each traversal argument is iterated for a single result only. If exactly one traversal is provided and it produces | ||
| a `Collection<String>`, the collection will be automatically unfolded into the set of labels removed; if more than | ||
| one traversal is provided, each must resolve to a single `String` label. | ||
|
|
||
| *Exceptions* | ||
|
|
||
| * If the graph's `LabelCardinality` does not permit label modification, an `IllegalStateException` will be thrown. | ||
| * If `dropLabel()` or `dropLabels()` would violate the minimum label count, an `IllegalStateException` will be thrown. | ||
| * If more than one traversal is provided and any of them produces a `Collection`, an `IllegalArgumentException` will | ||
| be thrown. | ||
|
|
||
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/DropLabelsStep.java[source], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#droplabel-step[reference] | ||
|
|
||
| [[all-step]] | ||
| === all() | ||
|
|
||
|
|
@@ -1525,6 +1603,41 @@ None | |
|
|
||
| None | ||
|
|
||
| [[elementmap-step]] | ||
| === elementMap() | ||
|
|
||
| *Description:* Converts elements to a `Map` representation containing the element's `id`, `label`, and properties. | ||
| For an `Edge`, the map also includes the `IN` and `OUT` vertex structures (each a nested map of `id` and `label`). | ||
|
|
||
| *Syntax:* `elementMap(String... propertyKeys)` | ||
|
|
||
| [width="100%",options="header"] | ||
| |========================================================= | ||
| |Start Step |Mid Step |Modulated |Domain |Range | ||
| |N |Y |N |`Element` |`Map` | ||
| |========================================================= | ||
|
|
||
| *Arguments:* | ||
|
|
||
| * `propertyKeys` - If `elementMap()` is provided a list of propertyKeys, then the result map will only contain | ||
| property entries specified by propertyKeys. If the list is empty, then all properties are included. | ||
|
|
||
| *Considerations:* | ||
|
|
||
| The label format in the map is controlled by source-level `with("multilabel")` and `with("singlelabel")` options, not | ||
| by the graph's `LabelCardinality`. When `"multilabel"` is present, the label value is a `Set<String>`; likewise when | ||
| `"singlelabel"` is present, it is a single `String`. The two options are mutually exclusive, configuring both | ||
| `"multilabel"` and `"singlelabel"` on the same source is rejected with a `VerificationException`. Note that is a | ||
| provider choice whether an unconfigured `GraphTraversal` defaults to `multilabel` or `singlelabel` semantics. The | ||
| reference implementation defaults to `singlelabel` semantics. | ||
|
|
||
| *Exceptions* | ||
|
|
||
| None | ||
|
|
||
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ElementMapStep.java[source], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#elementmap-step[reference] | ||
|
|
||
| [[format-step]] | ||
| === format() | ||
|
|
||
|
|
@@ -1637,6 +1750,49 @@ See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/j | |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java[source (sideEffect)], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#groupcount-step[reference] | ||
|
|
||
| [[label-step]] | ||
| === label() | ||
|
|
||
| *Description:* Maps an element to its label as a single string value. | ||
|
|
||
| *Syntax:* `label()` | ||
|
|
||
| [width="100%",options="header"] | ||
| |========================================================= | ||
| |Start Step |Mid Step |Modulated |Domain |Range | ||
| |N |Y |N |`Element` |`String` | ||
| |========================================================= | ||
|
|
||
| *Considerations:* | ||
|
|
||
| The `label()` step returns exactly one label string per element. For graphs that support multiple labels per vertex, | ||
| `label()` returns only one of the vertex's labels and the choice is non-deterministic (implementation-dependent | ||
| ordering). Use `labels()` to retrieve all labels reliably. | ||
|
|
||
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LabelStep.java[source], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#label-step[reference] | ||
|
|
||
| [[labels-step]] | ||
| === labels() | ||
|
Cole-Greer marked this conversation as resolved.
|
||
|
|
||
| *Description:* Maps an element to its labels, emitting one traverser per label. | ||
|
|
||
| *Syntax:* `labels()` | ||
|
|
||
| [width="100%",options="header"] | ||
| |========================================================= | ||
| |Start Step |Mid Step |Modulated |Domain |Range | ||
| |N |Y |N |`Element` |`String` | ||
| |========================================================= | ||
|
|
||
| *Considerations:* | ||
|
|
||
| For vertices with a single label, `labels()` emits one traverser (equivalent to `label()`). For multi-label vertices, | ||
| it emits one traverser per label. For vertices with zero labels (`ZERO_OR_MORE` mode), no traversers are emitted. | ||
|
|
||
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LabelsStep.java[source], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#labels-step[reference] | ||
|
|
||
| [[length-step]] | ||
| === length() | ||
|
|
||
|
|
@@ -2564,6 +2720,19 @@ the possible values are: | |
| ** 8 for including values (VertexProperty) | ||
| ** 15 for including all | ||
|
|
||
| *Considerations:* | ||
|
|
||
| The label format in the map is controlled by source-level `with("multilabel")` and `with("singlelabel")` options, not | ||
| by the graph's `LabelCardinality`. When `"multilabel"` is present, the label value is a `Set<String>`; likewise when | ||
| `"singlelabel"` is present, it is a single `String`. The two options are mutually exclusive, configuring both | ||
| `"multilabel"` and `"singlelabel"` on the same source is rejected with a `VerificationException`. Note that is a | ||
| provider choice whether an unconfigured `GraphTraversal` defaults to `multilabel` or `singlelabel` semantics. The | ||
| reference implementation defaults to `singlelabel` semantics. | ||
|
|
||
| *Exceptions* | ||
|
|
||
| None | ||
|
|
||
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java[source], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#valuemap-step[reference], | ||
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#propertymap-step[reference] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -166,6 +166,7 @@ TinkerGraph has several settings that can be provided on creation via `Configura | |
| |gremlin.tinkergraph.vertexPropertyIdManager |The `IdManager` implementation to use for vertex properties. | ||
| |gremlin.tinkergraph.defaultVertexPropertyCardinality |The default `VertexProperty.Cardinality` to use when `Vertex.property(k,v)` is called. | ||
| |gremlin.tinkergraph.allowNullPropertyValues |A boolean value that determines whether or not `null` property values are allowed and defaults to `false`. | ||
| |gremlin.tinkergraph.vertexLabelCardinality |The `LabelCardinality` for vertices. Options are `ONE` (default, single immutable label, backward-compatible with 3.x), `ONE_OR_MORE` (at least one label, mutable), or `ZERO_OR_MORE` (zero or more labels). See <<tinkergraph-multi-label>>. | ||
| |gremlin.tinkergraph.graphLocation |The path and file name for where TinkerGraph should persist the graph data. If a | ||
| value is specified here, the `gremlin.tinkergraph.graphFormat` should also be specified. If this value is not | ||
| included (default), then the graph will stay in-memory and not be loaded/persisted to disk. | ||
|
|
@@ -219,6 +220,36 @@ g.io("data/tinkerpop-crew.kryo").read().iterate() | |
| g.V().properties() | ||
| ---- | ||
|
|
||
| [[tinkergraph-multi-label]] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're missing a lot of docs updates. TinkerGraph isn't the story here. The story is that TinkerPop now has multi-label support. The entire reference guide, recipes, tutorials, etc. need review. At minimum, we have to conceptually introduce this change to the "structure" at the front end of the reference docs: https://tinkerpop.apache.org/docs/current/reference/#graph-structure We should be looking to explain this feature throughout the docs in a seamless fashion. |
||
| === Multi-Label Support | ||
|
|
||
| TinkerGraph supports multiple labels per vertex when `gremlin.tinkergraph.vertexLabelCardinality` is set to | ||
| `ONE_OR_MORE` or `ZERO_OR_MORE`. This enables use of the `addLabel()`, `dropLabel()`, `dropLabels()`, and `labels()` | ||
| traversal steps. | ||
|
|
||
| [gremlin-groovy] | ||
| ---- | ||
| conf = new BaseConfiguration() | ||
| conf.setProperty("gremlin.tinkergraph.vertexLabelCardinality", "ZERO_OR_MORE") | ||
| graph = TinkerGraph.open(conf) | ||
| g = traversal().with(graph) | ||
| g.addV("person","employee").property("name","marko").iterate() | ||
| g.V().has("name","marko").labels() <1> | ||
| g.V().has("name","marko").addLabel("manager").labels() <2> | ||
| g.V().has("name","marko").dropLabel("employee").labels() <3> | ||
| ---- | ||
|
|
||
| <1> The vertex was created with two labels. | ||
| <2> A third label is added. | ||
| <3> One label is removed. | ||
|
|
||
| The `hasLabel()` step works with multi-label vertices using OR semantics: `hasLabel("a","b")` matches any vertex that | ||
| has label "a" OR label "b". To match vertices having both labels, chain multiple `hasLabel()` calls: | ||
| `hasLabel("a").hasLabel("b")`. | ||
|
|
||
| This multi-label support applies to vertices only; an `Edge` must have exactly one label regardless of the | ||
| graph's configured `vertexLabelCardinality`. | ||
|
|
||
| [[tinkergraph-gremlin-tx]] | ||
| === Transactions | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.