Hi Yang, That seems like a reasonable proposal if we want to pursue multi-label support, but I would hesitate to deprecate single-label support in the process. I see TinkerPop as a related but distinct ecosystem from the one which gave rise to GQL, being heavily weighted toward Neo4j. One of the key advantages of the TinkerPop approach to property graphs, in my opinion, is its simplicity. Every edge is directed, connects exactly two vertices, and has exactly one label. Vertices have at most one label -- which I like to interpret as exactly one label with a distinguished default label. Sometimes constraints liberate, and I think this is the case here. The more degrees of freedom you introduce into the data model -- multi-label vertices and edges, undirected edges, hyperedges, etc. -- the more complex and less tractable the query and inference logic becomes. This is sure to be important as we start adding more schema-rich features to TP4.
So... my personal $0.02 are that while it is OK to provide levers for users to layer additional features like multi-label support on top of core TinkerPop, I will still try to keep the core as simple as possible, at least until the schema features settle down and we know how they would be impacted by deep changes to the data model. In concrete terms, that might mean continuing to support Element.label(), but also providing Element.labels() based on a configuration like the one you mentioned. When multi-label support is switched on, the label would allow some encoded label set -- like a comma-separated list of labels, normalized in alphabetical order (e.g. "Employee,Person") -- and the multi-label steps would operate on that. Classic single-label operations, however, would continue to work as usual, with no impact from multi-label support. Similar for other GQL constructs like undirected edges. Best regards, Josh On Wed, Jun 10, 2026 at 4:20 PM Yang Xia <[email protected]> wrote: > Hi all, > > I'd like to propose expanding label support in TinkerPop 4.0 to allow > multiple mutable labels on vertices and edges. > > Background: > > When TinkerPop was first developed, the property graph model did not > widely support anything other than a single immutable label. Since then, > multi-label has become more common; mutable labels and no-label options are > increasingly supported across graph databases. The GQL standard defines > both vertices and edges as having zero or more labels. > > Supporting multi-label and mutable labels fits relatively well into > Gremlin syntax and semantics. The notion of "no label" is more nuanced. It > makes sense for analytics use cases where algorithms don't care about > element classification, but less so for transactional cases where labels > serve as schema anchors. Rather than dictating one behavior, providers > would be free to configure the extent to which they wish to support > multilabel, if any. > > Proposal: > > The goal is to make multi-label opt-in for providers, with configuration > over which label cardinalities and element types to support. Providers that > wish to remain single-label can do so without breaking changes. > > For TinkerPop's reference implementation, I propose: > > Vertices: 0..N label support (with 0..1, 1..1 and 1..N as configurable > options) > Edges: 0..1 label support initially, with the foundation in place for N > labels later > > Key structural changes: > - Element.label() deprecated in favor of Set<String> labels(). The label() > method returns the first label for backward compatibility. The default > labels() implementation in Element delegates to > Collections.singleton(label()), so existing providers work without changes. > - Serialization uses List<String> for all label fields in GraphBinary V4 > and GraphSON V4. The wire format is already list-based, this change > populates the list fully rather than always writing a singleton. > > New steps: > - addLabel(String, String...), dropLabel(String, String...), dropLabels(), > and labels() for streaming all labels. > - with('multilabel') configuration for valueMap()/elementMap() where > single-label return remains the default, with multi-label output when > configured. > > While multiple labels add some complexity to TinkerPop's model, this opens > the door for providers who want to expand their database models and moves > toward interoperability with GQL's label semantics. > > I plan to draft a PR soon with a design proposal and initial > implementation. The goal is to include some level of multi-label support > for the upcoming beta release, setting a good foundation for 4.0.0 GA > feedback. > > Please share any thoughts, concerns, or questions in this thread. > > Thank you, > > Yang >
