Skip to main content


Schema predicates are similar to relational ledger columns, however there are fewer restrictions (any predicate can be attached to any subject, unless a restriction is put in place using a spec).

Remember that Fluree schema are stored in the ledger in the same way as any other type of information. This means that because _predicate is a type of thing in our ledger, there is a _predicate collection (similar to a relational ledger table). Furthermore, the _predicate collection has its own predicates.

_predicate Predicates

Below are the built-in predicates for the _predicate collection. As mentioned in the collection section, you can add additional predicates if you wish.

_predicate/namestring(required) Actual predicate name. Must be namespaced, and convention is to namespace it using the collection name you intend it to be used within. Technically any predicate can be placed on any subject, but using a spec can restrict this behavior. Note that if you intend to use GraphQL tools, predicate names must conform to /[_A-Za-z][_0-9A-Za-z]*/. If you do not conform to this standard, queries issued to the /graphql endpoint will still work, but many GraphQL tools will not.
_predicate/docstring(optional) Doc string for this predicate describing its intention. This description is also used for GraphQL automated schema generation.
_predicate/typetag(required) Data type of this predicate such as string, integer, or a reference (join) to another subject - ref. See table below for valid data types.
_predicate/uniqueboolean(optional) True if this predicate acts as a primary key. Unique predicates can be used for idsubject (as the _id value in a transaction or query). (Default false.)
_predicate/multiboolean(optional) If this is a multi-cardinality predicate (holds multiple values), set to true. (Default false.)
_predicate/indexboolean(optional) True if an index should be created on this predicate. A predicate marked as unique automatically will generate an index and will ignore the value specified here. (Default false.)
_predicate/upsertboolean(optional) Only applicable to predicates marked as unique. If a new subject transaction using this predicate resolves to an existing subject, update that subject. By default the transaction will throw an exception if a conflict with a unique predicate exists.
_predicate/noHistoryboolean(optional) By default, all history is kept. If you wish to turn this off for a certain subject, set this flag to true. Queries, regardless of time travel, will always show the current value.
_predicate/componentboolean(optional) For type 'ref' predicates only. Mark true if this predicate refers to a subject which only exists as part of the parent subject. If true, and the parent subject is deleted, the subject referenced by this predicate will also be deleted automatically. (Default false.)
_predicate/spec[ref](optional) A multi-cardinality list of refs, which reference entities in the _fn collection. These specs restricts what is allowed in this _predicate. To see how to write a function, see the function section.
_predicate/specDocstring(optional) Optional docstring to describe the specs. Is thrown when any spec fails.
_predicate/deprecatedboolean(optional) True if this v is deprecated. Reads and writes are still allowed, but might give warnings in the API.
_predicate/txSpec[ref](optional) A multi-cardinality list of refs, which reference entities in the _fn collection. This predicate allows you to set specifications for all of the flakes pertaining to a certain predicate. To see how to write a function, see the function section.
_predicate/txSpecDocstring(optional) Optional docstring to describe the txSpecs. Is thrown when any txSpec fails.
_predicate/restrictCollectionstring(optional) Only applicable to predicates of ref (reference) types. It will restrict references to only be allowed from the specified collection.
_predicate/restrictTagboolean(optional) Only applicable to predicates of type tag. If true, a tag, which corresponds to this predicate object, must exist before adding predicate-object pair.
_predicate/encryptedboolean(Not in production yet, optional) Expects the value to come in as an encrypted string. Type checking will be disabled, and ledger functions won't be permitted on this value.
_predicate/fullTextboolean(optional) If true, full text search enabled on this ledger. By default, the language for a Fluree ledger is set to English. You can change the default language in ledger settings.
_predicate/retractDuplicatesboolean(optional) If false (default), when a transaction creates a new flake that already exists it does not update the existing data. When true, it will always force a retraction/insertion.

Predicate Types

Supported predicate types (_predicate/type) are as follows:

stringUnicode string (_type/string)
refReference (join) to another collection (_type/ref)
tagA special tag predicate. Tags are auto-generated, and create auto-resolving referred entities. Ideal for use as enum values. Also they allow you to find all entities that use a specific tag. (_type/tag)
int32 bit signed integer (_type/int)
long64 bit signed integer (_type/long)
bigintArbitrary sized integer (more than 64 bits) (_type/bigint)
float32 bit IEEE double precision floating point (_type/float)
double64 bit IEEE double precision floating point (_type/double)
bigdecIEEE double precision floating point of arbitrary size (more than 64 bits) (_type/bigdec)
instantMillisecond precision timestamp from unix epoch. Uses 64 bits. (_type/instant)
booleantrue/false (_type/boolean)
uriURI formatted string (_type/uri)
uuidA UUID value. (_type/uuid)
bytesMust input bytes as a lowercase, hex-encoded string (_type/bytes)
jsonArbitrary JSON data. The JSON is automatically encoded/decoded (UTF-8) with queries and transactions, and JSON structure can be validated with a spec. (_type/json)

Notice there is no array type. If you want a predicate to have multiple objects (values), you need to specify a _predicate/type, and then also specify "multi": true.

Creating Predicates

In order to create a predicate, you only need to specify what type of subject you are creating (_predicate), a name, and a type. The name for a predicate should be namespaced with the relevant collection (as in all predicates in the person collection should begin with person/). There are also a host of other predicate predicates, which are listed in the linked section, but they are not required.

If you would like a _predicate/spec or txSpec, which limits the allowed values for a predicate, see the function section.

"_id": "_predicate",
"name": "person/handle",
"doc": "The person's unique handle",
"unique": true,
"type": "string"
"_id": "_predicate",
"name": "person/fullName",
"doc": "The person's full name.",
"type": "string",
"index": true
"_id": "_predicate",
"name": "person/follows",
"doc": "Any persons this subject follows",
"type": "ref",
"restrictCollection": "person"

Adding a Predicate to _predicate

_predicate is a built-in ledger collection with built-in predicates. This does not mean, for instance, that you cannot add predicates. For example, you may want to add a _predicate/longDescription predicate, where you store a longer version of _predicate/doc.

You can do this by adding a new predicate:

"_id": "_predicate",
"name": "_predicate/longDescription",
"type": "string"

After you add this predicate, you can update any existing predicates to include a long description:

"_id": ["_predicate/name", "person/handle"],
"longDescription": "I have a lot to say about this predicate, so this is a longer description about the person/handle predicate"

And you can create new predicates with a _predicate/longDescription:

"_id": "_predicate",
"name": "_user/age",
"type": "int",
"longDescription": "I have a lot to say about this predicate, so this is a longer description about the _user/age predicate"

Updating a Predicate in _predicate

Although you can change built-in collection predicates, we do not recommend doing so, as your changes may break certain aspects of schema validation.

One commonly-requested safe change, however, is to allow _predicate/name to be upsertable. By default, _predicate/name does not allow upsert, meaning if you try to create a new predicate with the name of already existing predicate, an error will be thrown. You can change this, however, by editing the predicate, _predicate/name. To see all the existing predicates for the _predicate/name predicate, you can issue the following query:

"select": ["*"],
"from": ["_predicate/name", "_predicate/name"]

The default features of _predicate/name are:

"_predicate/name": "_predicate/name",
"_predicate/doc": "Predicate name",
"_predicate/type": "string",
"_predicate/unique": true,
"_id": 10 // id depends on Fluree version

As we can see, there is no upsert key in the predicate, so by default upsert is false. To change this, we can issue:

"_id": ["_predicate/name", "_predicate/name"],
"upsert": true
Now, we allow upsert for the `_predicate/name` predicate.

Query All Predicates

To see all of the predicates in a collection, you can use an analytical query with a filter, like below. To see all the predicates from any given collection, just replace _collection with the name of any collection.

"select": { "?predicate": ["*"] },
"where": [
["?predicate", "_predicate/name", "?name"],
{ "filter": ["(re-find (re-pattern \"^_collection\") ?name)"] }