Skip to content

[TINKERPOP-3261] Enable multiple labels on vertex with configurable label cardinality#3483

Draft
xiazcy wants to merge 6 commits into
masterfrom
multi-label-experiment
Draft

[TINKERPOP-3261] Enable multiple labels on vertex with configurable label cardinality#3483
xiazcy wants to merge 6 commits into
masterfrom
multi-label-experiment

Conversation

@xiazcy

@xiazcy xiazcy commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Introduces configurable label cardinality for graph elements. Vertex cardinality is user-configurable; edge cardinality defaults to ONE and is not yet exposed as a configuration option but uses the same underlying infrastructure.

Vertices can now have zero, one, or many labels controlled by LabelCardinality (defaults to ONE for full backward compatibility). New traversal steps labels(), addLabel(), dropLabel(), and dropLabels() enable label retrieval and mutation. Edge labels remain fixed at cardinality ONE.

Notes on design:

  • LabelCardinality is a pure data descriptor enum with min()/max()/mutable fields. Validation logic lives in a separate LabelCardinalityValidator utility.
  • mergeV() uses append-only semantics for onMatch labels (no implicit replacement).
  • hasLabel('a','b') is OR semantics, use hasLabel('a').hasLabel('b') for AND semantics.
  • with("multilabel") is source-level setting for backwards compatibility. Configures elementMap()/valueMap() to return labels as a Set instead of a single String by default.
  • Older serialization formats (GraphSON V1/V2/V3, Gryo) silently use label() which returns one non-deterministic label. Only GraphBinary and GraphSON V4 preserve the full label set.

Commits:

  1. Vertex prototype: labels() step, addLabel/dropLabel steps, Element.labels() API, TinkerGraph implementation
  2. Edge API surface: edge label overrides (validate-and-throw for ONE), transaction fix, feature tests
  3. GLV implementations: .NET, Go, JavaScript, Python support
  4. Cardinality + with('multilabel'): LabelCardinality enum, LabelCardinalityValidator, append-only merge, source-level config
  5. Defaults, strategy, docs, tests: TinkerGraph ONE default, LabelsDropVerificationStrategy, reference/upgrade/provider docs, CHANGELOG

Configuration

To Enable multi-label in TinkerGraph:
gremlin.tinkergraph.vertexLabelCardinality=ZERO_OR_MORE

Testing

  • Feature tests (Gherkin): Labels.feature, AddLabel.feature, DropLabel.feature, MergeVertex multi-label scenarios
  • Unit tests: LabelMutationStepTest, LabelCardinalityTest, LabelReplacePatternValidationTest, hasLabel OR/AND semantics

VOTE +1

xiazcy added 6 commits June 25, 2026 09:29
- Add labels() flatMap step emitting each label as a separate traverser
- Add addLabel()/dropLabel()/dropLabels() sideEffect mutation steps
- Add Element.labels() API returning Set<String>
- Update grammar for label mutation and multi-label addV()
- Add GraphBinary and GraphSON V4 serialization for multi-label
- Add MergeVertex multi-label support
- Implement in TinkerGraph with thread-safe ConcurrentHashMap.newKeySet()
- Add unit tests for label mutation, properties, and GremlinLang
- Add label mutation API on edges (validates and throws for ONE cardinality)
- Add edge binary and GraphSON serialization for label set
- Fix multi-label handling in TinkerTransactionGraph
- Add Gherkin feature tests for labels(), addLabel(), dropLabel()
- Add event/mutation support for label changes on edges
- Thread-safe edge label storage with ConcurrentHashMap.newKeySet()
- Wire up GLV test infrastructure for multi-label scenarios
- .NET: GraphTraversal, GraphTraversalSource, Edge/Vertex structures, binary serializers
- Go: graphTraversal, graph structures, binary serializer/deserializer
- JavaScript: graph-traversal.ts, graph.ts, binary serializers
- Python: graph_traversal.py, graph.py, graphbinaryV4.py
- Update GLV test translations and Gherkin step bindings
- Add MergeEdge and AddEdge feature test scenarios
…'multilabel')

- Introduce LabelCardinality enum as pure data descriptor (min/max/mutable)
- Add LabelCardinalityValidator for separated constraint enforcement
- Add Graph.Features for label cardinality declaration
- Update MergeVertex/MergeEdge with append-only label semantics on onMatch
- Simplify with('multilabel') to source-level only via OptionsStrategy
- Remove redundant step-level with(WithOptions.multilabel) path
- Add serialization support for GraphML, GraphSON v1/v2/v3, Gryo
- Add label replace pattern validation tests
…ocs and tests

- Default TinkerGraph to LabelCardinality.ONE (backward-compatible)
- Add tinkergraph-multilabel.properties for multi-label graph config
- Add LabelsDropVerificationStrategy to prevent accidental labels().drop()
- Add multi-label TinkerGraph to Gremlin Server integration test config
- Update GLV Gherkin infrastructure for multi-label test graph
- Add LabelCardinalityTest for verifying cardinality modes
- Add feature tests: drop non-existent label, mergeV onCreate/onMatch
- Add unit tests: null/empty args, hasLabel OR/AND semantics, index cycle
- Add reference docs for addLabel, dropLabel, labels steps
- Add TinkerGraph multi-label configuration docs
- Add provider semantics docs for new steps
- Add upgrade docs for users and providers
- Add CHANGELOG entries
- Remove unrelated addE() no-arg grammar/API addition
- Fix vertexLabelCounts to handle multi-label vertices
@xiazcy xiazcy force-pushed the multi-label-experiment branch from 93b3b0c to 9f66466 Compare June 25, 2026 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant