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]

Reply via email to