The fields of a schema define the allowed content for the properties of the documents having this schema.
Simple Types
The Nuxeo Platform internal data model is based on the following data types:
String
: a Unicode string value.Long
: a 64-bit signed integer.Double
: a double-precision 64-bit IEEE 754 floating point number.Boolean
: a boolean data type.Calendar
: a date, more specifically an instant in time with milliseconds resolution.
Calendar Timezone
Because most storage layers are unable to store an instant in time with an associated timezone to interpret it, dates in the Nuxeo Platform are usually translated to the server timezone, and are read back with the server timezone.
For instance one could write a date as "1st January 2017 at 2pm London Time" but if the server is working in the Paris Time timezone, it would be read back as "1st January 2017 at 3pm Paris Time", because there is a one hour difference between London Time and Paris Time (this is a simplification of how timezones work but is sufficient here). The important point is that both "1st January 2017 at 2pm London Time" (the value written) and "1st January 2017 at 3pm Paris Time" (the value read) represent the same instant in time.
Arrays
A Nuxeo Platform field can also store an array of the simple types described above.
In JSON an array value would be represented for instance as:
["a", "b", "c", "d"]
Complex Types
A Nuxeo Platform field can also store a sub-document defined by a map of sub-field to value.
In JSON a complex value would be represented for instance as:
{
"foo": 1,
"bar": "something",
"baz": [42,1729]
}
Complex types can contain other complex types:
{
"foo": 1,
"bar": "something",
"baz": {
"name": "bob",
"address": "here",
"age": 12
}
}
Complex Lists
A Nuxeo Platform field can also store a list of complex types.
In JSON a complex list value would be represented for instance as:
[{
"foo": 1,
"bar": "something",
"baz": [42,1729]
},{
"foo": 2,
"bar": "something else",
"baz": [1,2,3,5,7,11]
}]
XSD Mapping
A standard set of XSD types are allowed in Nuxeo Platform schemas, and are mapped to the internal data model as follows:
XSD Type | Java Type |
---|---|
xsd:string | String |
xsd:normalizedString | String |
xsd:long | Long |
xsd:unsignedLong | Long |
xsd:integer | Long |
xsd:int | Long |
xsd:unsignedInt | Long |
xsd:positiveInteger | Long |
xsd:nonPositiveInteger | Long |
xsd:nonNegativeInteger | Long |
xsd:short | Long |
xsd:unsignedShort | Long |
xsd:double | Double |
xsd:float | Double |
xsd:decimal | Double |
xsd:boolean | Boolean |
xsd:datetime | Calendar |
xsd:date | Calendar |
xsd:time | Calendar |
Unset Values
All fields allow an additional unset value, which is expressed differently depending on the language (null
in Java or JavaScript for example) or storage used (NULL
in SQL databases, unset in MongoDB).
Some storage mechanisms, like MongoDB, distinguish between a null
value and an unset value, but Nuxeo Platform takes care that at the storage level there are only unset values, to minimize document size and for consistency.
For arrays and complex lists, no distinction is made between an unset value and an empty array/list; they are semantically equivalent for the Nuxeo Platform data model.
Default values
A schema can express that a field has a default value. When this is the case, it replace the unset value with this default. In particular this means that one can never read a null
from a field that has a default value.
Delta Updates
Since Nuxeo Platform 6.0 (NXP-15103) a new update model for Long
properties is available using DeltaLong
.
A DeltaLong
is stored as a Long
, but when used in the Java API to update a field (DocumentModel.setPropertyValue()
) it specifies that the update should be done as an increment at the storage level rather than as a replacement of the old value. This allows for concurrent updates that don't lose value.
The standard usage to add a value "count" to a property "myprop" is:
long count = 1;
Number oldValue = (Number) doc.getPropertyValue("myprop");
Number newValue = DeltaLong.valueOf(oldValue, count);
doc.setPropertyValue("myprop", newValue);
DeltaLong.valueOf(oldValue, count)
should be used in preference over new DeltaLong(oldValue, count)
because it can deal with the case where the old value is null
or already a DeltaLong
(the latter can happen if you're re-updating a property which hasn't been saved yet).
When using a SQL backend, this will emit code like (supposing the old value was 41):
UPDATE myschema SET myprop = myprop + 1 WHERE id = 'the-doc-id';
instead of:
UPDATE myschema SET myprop = 42 WHERE id = 'the-doc-id';
which gives different results if two threads are executing it at the same time.
For a MongoDB backend, the update will be done using:
db.default.update(
{ "ecm:id": "the-doc-id" },
{ $inc: { "myprop": 1 } }
)
instead of :
db.default.update(
{ "ecm:id": "the-doc-id" },
{ $set: { "myprop": 42 } }
)
Property Characteristics
A property characteristic represents additional information a property could hold such as secured, deprecated or indexed.
See below the basic contribution for a property characteristic:
<component name="my.component.name">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
<property schema="SCHEMA" name="PROPERTY" ... />
</extension>
</component>
SCHEMA
is the full schema name and PROPERTY
is the path representing the property, for example:
dublincore
andcreated
for thedc:created
propertyfiles
andfiles/*/file/name
for thefiles:files/*/file/name
property.
Secured
When a property is secured, only Administrators can edit them. This prevents regular users to edit sensitive data.
Contribute the xml below to make a property secured:
<component name="my.component.name">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
<property schema="SCHEMA" name="PROPERTY" secured="true" />
</extension>
</component>
The following properties are secured by default:
dc:created
dc:modified
dc:creator
dc:contributors
dc:lastContributor
IndexOrder
Since Nuxeo 2021.8, you can contribute indexes to be created at Nuxeo startup. Nuxeo supports these types of index: ascending
, descending
, and none
to disable the index.
Contribute the xml below to make a property indexed:
<component name="my.component.name">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
<property schema="SCHEMA" name="PROPERTY" indexOrder="ascending" />
<property schema="SCHEMA" name="PROPERTY" indexOrder="descending" />
</extension>
</component>
Deprecation
You can mark a property as deprecated or removed with or without a fallback (present in the same schema).
A deprecated property still has its declaration in the schema XSD. A warn log will be printed if the code tries to read or write this property. The fallback takes the precedence when reading the property, if it is null then the deprecated property is returned. During write operations, both properties receive the new value.
A removed property doesn't have anymore its declaration in the schema XSD. An error log will be printed if the code tries to read or write this property. Null will be returned and nothing will be stored if no fallback is defined, otherwise, the fallback takes the precedence.
Contribute the xml below to make a property deprecated or removed:
<component name="my.component.name">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
<property schema="SCHEMA" name="PROPERTY" deprecation="deprecated" />
<property schema="SCHEMA" name="PROPERTY" deprecation="removed" fallback="ANOTHER_PROPERTY" />
</extension>
</component>