How does @set make single and multiple JSON-LD values consistent?

The Citead team, updated

In short. In a JSON-LD context, @container: @set keeps a term's compacted value in an array even when it has one value.

Definition: In JSON-LD, @set describes an unordered collection. In a context, "@container": "@set" tells compaction to keep the term's value in an array, so a property with one value and a property with several values have the same JSON shape.

Key facts

  • The W3C JSON-LD 1.1 specification describes @set as the keyword for unordered sets.
  • A set object is a map with an @set entry. The API specification allows an optional @index key and no other entries in that object.
  • A term associated with an @set container is represented as an array even when it has one value.
  • JSON-LD 1.1 allows @set to be combined with other container specifications so indexed values can also use arrays consistently.

What is a set object?

The JSON-LD 1.1 Processing Algorithms and API specification defines a set object as a map with an @set entry. It may also contain an @index key. This form makes the collection explicit in document data:

{
  "@set": ["joe", "bob", "jaybee"]
}

The W3C definition of sets states that @set describes unordered sets, while @list describes ordered lists. Processing removes the @set wrapper from the document body as syntactic sugar. The values remain a collection in the expanded representation, where the example becomes an array of value objects.

What does a set container change in a context?

A context can attach the set rule to a term:

{
  "@context": {
    "nick": {
      "@id": "https://example.com/nick",
      "@container": "@set"
    }
  },
  "nick": ["joe", "bob", "jaybee"]
}

The W3C sets section says that values of terms with an @set container are always arrays, even when a single value would otherwise be compacted to a scalar or object. This gives software one property shape to process. The same section says arrays of values are unordered by default, and a context can make that choice explicit with @container set to @set.

The rule applies during compaction. The API specification's compaction algorithm sets its array flag to true when JSON-LD 1.1 processing is used and the active term's container mapping includes @set. A single value therefore stays inside an array in compacted output.

Can @set be combined with another container?

JSON-LD 1.1 permits @set in an array of container specifications. For example, a language map can request both language indexing and stable array output:

{
  "@context": {
    "@version": 1.1,
    "label": {
      "@id": "http://example.com/vocab/label",
      "@container": ["@language", "@set"]
    }
  }
}

The W3C JSON-LD API specification includes @set in the container selection used by compaction and defines the array flag from that container mapping. The syntax specification gives the combined @language and @set form as a JSON-LD 1.1 example. The same pattern is available for the @id and @index container combinations described by the specification.

FAQ

Does @set mean that array order is significant?

No. The W3C specification describes a set as unordered and says that order may change when a document is processed. Use @list when the data is an ordered list.

Is a set object the same as a set container?

They operate at different levels. A set object is a JSON-LD map with an @set entry in document data. A set container is a context mapping that controls the compacted representation of a term.

What should a parser expect for a one-value property?

When the term has "@container": "@set", the compacted value is an array containing that one value. The API compaction algorithm uses the container mapping to select array output.

Sources

  1. W3C, "JSON-LD 1.1", 16 July 2020
  2. W3C, "JSON-LD 1.1 Processing Algorithms and API", 16 July 2020

Check how a page reads to answer engines. Open the GEO score analyzer

Test a page and see what to fix first

The analysis usually takes less than 10 seconds and needs no account.

400,000+ pages scored in the public benchmark