spmallette commented on code in PR #3483: URL: https://github.com/apache/tinkerpop/pull/3483#discussion_r3553153086
########## docs/src/upgrade/release-4.x.x.asciidoc: ########## @@ -186,6 +186,93 @@ For full details on the interceptor API for each language variant, refer to the each GLV's documentation in the link:https://tinkerpop.apache.org/docs/x.y.z/reference/#gremlin-drivers-variants[Gremlin Drivers and Variants] reference. +==== Multi-Label Support + +Until now, vertices in the property graph model were limited to a single, immutable label assigned at creation. This +release introduces configurable label cardinality, allowing vertices to carry multiple labels that can be added and +removed over their lifetime. + +The feature is controlled by `LabelCardinality`, a graph-level setting that defaults to `ONE`, preserving the +existing single-label behavior. To enable multi-label in TinkerGraph, set the vertex label cardinality in the graph +properties: + +``` +gremlin.tinkergraph.vertexLabelCardinality=ZERO_OR_MORE +``` + +The three modes are `ONE` (single, immutable, the 3.x default), `ONE_OR_MORE` (mutable, minimum one), and +`ZERO_OR_MORE` (fully flexible). Edge labels remain fixed at `ONE`. + +With multi-label enabled, several new traversal steps become available: + +```text +gremlin> g.addV('person','employee').property('name','marko') +==>v[0] +gremlin> g.V().has('name','marko').addLabel('manager') +==>v[0] +gremlin> g.V().has('name','marko').labels() +==>person +==>employee +==>manager +gremlin> g.V().has('name','marko').dropLabel('employee').labels() +==>person +==>manager +``` + +The `labels()` step is a flatMap that emits one traverser per label, unlike `label()` which returns a single string. +For single-label vertices the two behave identically. + +The `mergeV()` step accepts a list for `T.label` to match or create multi-label vertices. The `onMatch` option uses +append-only semantics: new labels are added, existing labels are preserved: + +```text +gremlin> g.mergeV([(T.label): ['person','employee'], name: 'marko']) +==>v[0] +gremlin> g.mergeV([(T.label): 'person', name: 'marko']).option(Merge.onMatch, [(T.label): 'director']) +==>v[0] +``` + +By default, `elementMap()` and `valueMap()` continue to return labels as a single string. To receive all labels as a +set, use `with("multilabel")` either per-traversal or as a persistent source configuration: + +```text +// assuming a vertex with labels [person, employee, manager] and name "marko" +gremlin> g.with("multilabel").V().has('name','marko').elementMap() +==>{id=0, label=[manager, person, employee], name=marko} +gremlin> g.V().has('name','marko').elementMap() +==>{id=0, label=manager, name=marko} +``` + +To avoid repeating `with("multilabel")` on every traversal, create a persistent source: + +```text +gremlin> gml = g.with("multilabel") +==>graphtraversalsource[tinkergraph[vertices:1 edges:0], standard] +gremlin> gml.V().has('name','marko').elementMap() +==>{id=0, label=[manager, person, employee], name=marko} +gremlin> gml.V().has('name','marko').valueMap(true) +==>{id=0, label=[manager, person, employee], name=[marko]} +``` + +Note the following behavioral details: + +* The deprecated `label()` step returns a single, non-deterministic label when multiple labels are present. Always + use `labels()` to retrieve the full set reliably. +* When a source is configured with `with("multilabel")`, the label output can be forced back to a single string + per-traversal using `with("singlelabel")`. This is useful for providers that enable multi-label output by default + but need an escape hatch for backward compatibility. Note that when both options are present on the same source, + `"singlelabel"` always takes precedence regardless of the order in which they were applied. +* Serialization via GraphSON V1/V2/V3 or Gryo only transmits one label per vertex (using `label()`). Multi-label data Review Comment: do we have a GraphSON v1/v2/v3 anymore in 4.0? We're running into Gryo issues now - is that single label note relevant once we fix that? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
