...
Page Properties |
---|
|
Product Version |
|
---|
Report Note |
|
---|
Assignee |
|
---|
Resources & Remarks Modification History Name | Date | Product Version | Action |
---|
Antje | 11 JUN 2021 | 2021 Summer | Page created and writing started. | Agnieszka | 26 JUL 2021 | 2021 Summer | rLANG |
|
Excerpt |
---|
This example tutorial provides explanations and code examples to get an idea on how to define and specify structured data properties and on how to query them. |
Section |
---|
|
Column |
---|
Table of Contents Table of Contents |
---|
maxLevel | 3 |
---|
exclude | (Table of Contents|Read on|Managing the Schema|Importing Documents via Core API|Search Query Language) |
---|
|
|
|
Introduction
yuuvis® Momentum offers a property type for the storage of structured data in JSON format. Thus, it is possible to store interleaved data structures in a queryable way without defining each single sub-property in the schema. The structured data properties should NOT be considered to replace the concept of a well-defined schema. They should be used only if the handling of objects' metadata via the conventional property definitions is not reasonable. Especially, if the structure of metadata and/or the availability of properties differs a lot for the individual object instances, the schema might grow up to a really long list of scarcely used properties. This can be avoided by the usage of a property field that can store a JSON structure as value. In this tutorial, the bibliographic information of media in a library is considered an example use case. For this purpose, the set of information for each medium is provided in JSON structure following the concept of BibJSON.
>> Code examples in gitHubGitHub
Requirements
This tutorial is dedicated to experienced users. Please find information on requirements, maven and client configuration in our "Importing Documents via Core API" tutorial. The handling of any IOException is demonstrated there, too.
Definition in the Schema
In the context of the library example, the below displayed app schema is used. It contains two property definitions and one object type definition referencing the properties. The first property bibjsonsample:bibjson
has the property type structureddata
. Its id
matches the expression expected for the validation and the cardinality
is single
which is the only accepted value.
>> Structured Data Properties
This property will be used for the storage of the BibJSON structure containing the bibliographic information of the corresponding medium. The second property bibjsonsample:locations
allows for the assignment of a list of strings indicating storage locations if a printed version is available for the corresponding medium. In the object type definition of bibjsonsample:medium
, both properties are referenced. Additionally, a binary content file can be assigned if necessary as defined in line 25 with the value allowed
for the contentStreamAllowed
attribute contentStreamAllowed
.
Code Block |
---|
language | xml |
---|
title | Example Schema |
---|
linenumbers | true |
---|
|
<?xml version="1.0" encoding="utf-8"?>
<schema xmlns="http://optimal-systems.org/ns/dmscloud/schema/v5.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://optimal-systems.org/ns/dmscloud/schema/v5.0/ dmsCloud-schema.xsd">
<propertyStructuredDataDefinition>
<id>bibjsonsample:bibjson</id>
<description>field for the BibJSON structure identifying and describing the medium</description>
<propertyType>structureddata</propertyType>
<cardinality>single</cardinality>
<required>false</required>
</propertyStructuredDataDefinition>
<propertyStringDefinition>
<id>bibjsonsample:locations</id>
<description>field for storage locations of printed versions of the medium</description>
<propertyType>string</propertyType>
<cardinality>multi</cardinality>
<required>false</required>
</propertyStringDefinition>
<typeDocumentDefinition>
<id>bibjsonsample:medium</id>
<baseId>system:document</baseId>
<propertyReference>bibjsonsample:bibjson</propertyReference>
<propertyReference>bibjsonsample:locations</propertyReference>
<contentStreamAllowed>allowed</contentStreamAllowed>
</typeDocumentDefinition>
</schema> |
The schema for the bibjsonsample
app bibjsonsample
is imported via the endpoint POST /api/system/apps/{app}/schema endpoint.
More details and further examples on schema handling are provided in the following tutorial:
>> Managing the Schema
...
Specifying Values during Import
Two example objects will be created as instances of the object type abbBibjsonsample:medium
object type. Both of them get are assigned a BibJSON value for the property appbibjsonsample:bibjson
assigned to themproperty.
>> Structured Data in Import Bodies
...
The first example object is a book. The bibliographic information stored in the property appBibjsonsample:bibjson
, property contains one integer value specified in line 21, all . All other sub-values are stored as strings. In addition to the property appBibjsonsample:bibjson
property, two storage locations for printed versions are specified.
Code Block |
---|
language | yml |
---|
title | import request Import Request for a bookBook |
---|
linenumbers | true |
---|
|
{
"objects": [{
"properties": {
"objectTypeId": {
"value": "appBibjsonsample:medium"
},
"appBibjsonsample:bibjson": {
"value": {
"type": "book",
"title": "My Book Title",
"author": [
{"name": "Heinrich Schuetzel"},
{"name": "Maximilian Sturz"}
],
"year": "1995",
"owner": "My Library",
"id": "ID_of_book",
"url": "http://mylibrary.com/ebooks/36513466534",
"publisher": "Example Verlag Mustershagen",
"edition": {
"number": 2,
"language": "English"
},
"identifier":[
{
"id": "0002-9327",
"type": "issn"
}
]
}
},
"appBibjsonsample:locations": {
"value": [
"central library, CN-3214-5324",
"branch library east, 43-654b"
]
}
}
}]
} |
Code Block |
---|
language | yml |
---|
title | import response for the bookImport Response for a Book |
---|
linenumbers | true | collapse | true |
---|
|
{
"objects": [
{
"properties": {
"system:objectId": {
"value": "aab2b4d9-e829-45dd-981a-2f19a688592d"
},
"system:baseTypeId": {
"value": "system:document"
},
"system:objectTypeId": {
"value": "appBibjsonsample:medium"
},
"system:createdBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:creationDate": {
"value": "2021-06-14T13:10:52.280Z"
},
"system:lastModifiedBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:lastModificationDate": {
"value": "2021-06-14T13:10:52.280Z"
},
"system:versionNumber": {
"value": 1
},
"system:tenant": {
"value": "default"
},
"system:traceId": {
"value": "5681d3bddb4279de"
},
"appBibjsonsample:bibjson": {
"value": {
"type": "book",
"title": "My Book Title",
"author": [
{
"name": "Heinrich Schuetzel"
},
{
"name": "Maximilian Sturz"
}
],
"year": "1995",
"owner": "My Library",
"id": "ID_of_book",
"url": "http://mylibrary.com/ebooks/36513466534",
"publisher": "Example Verlag Mustershagen",
"edition": {
"number": 2,
"language": "English"
},
"identifier": [
{
"id": "0002-9327",
"type": "issn"
}
]
}
},
"appBibjsonsample:locations": {
"value": [
"central library, CN-3214-5324",
"branch library east, 43-654b"
]
}
}
}
]
} |
The second example object is a collection of articles without corresponding printed versions. The structure of the JSON value for the property appBibjsonsample:bibjson
looks property looks completely different.
Code Block |
---|
language | yml |
---|
title | import request Import Request for a collectionCollection |
---|
linenumbers | true |
---|
|
{
"objects": [{
"properties": {
"objectTypeId": {
"value": "appBibjsonsample:medium"
},
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"collection": "ym_concepts",
"label": "yuuvis(R) Momentum Core Concepts",
"description": "Documentation for yuuvis(R) Momentum Core in a structured, theoretical way, with links to the tutorial section.",
"id": "ID_of_collection",
"owner": "OS",
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T11:05:17.166Z",
"source": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/Concepts",
"records": 2
},
"records": [
{
"collection": "ym_concepts",
"type": "article",
"title": "Schema - Defining Object Types",
"id": "ID_of_schema_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/Schema+-+Defining+Object+Types",
"author":[
{"name": "Heinrich Schuetzel"},
{"name": "George Trader"},
{"name": "Johann Fluss"}
],
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T08:53:23.532Z"
},
{
"collection": "ym_concepts",
"type": "article",
"title": "Search Query Language",
"id": "ID_of_query_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/Search+Query+Language",
"author":[
{"name": "Andrea Schumann"},
{"name": "Franz Lissner"},
{"name": "Hans Kammer"},
{"name": "Johann Fluss"}
],
"created": "2020-06-16T14:03:01.833Z",
"modified": "2021-06-02T09:54:12.643Z"
}
]
}
}
}
}]
} |
Code Block |
---|
language | yml |
---|
title | import response for the collectionImport Response for a Collection |
---|
linenumbers | true | collapse | true |
---|
|
{
"objects": [
{
"properties": {
"system:objectId": {
"value": "3d4a67be-3341-4317-bb57-c48ea7ab0a1a"
},
"system:baseTypeId": {
"value": "system:document"
},
"system:objectTypeId": {
"value": "appBibjsonsample:medium"
},
"system:createdBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:creationDate": {
"value": "2021-06-14T13:11:57.770Z"
},
"system:lastModifiedBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:lastModificationDate": {
"value": "2021-06-14T13:11:57.770Z"
},
"system:versionNumber": {
"value": 1
},
"system:tenant": {
"value": "default"
},
"system:traceId": {
"value": "22839c5775801e9c"
},
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"collection": "ym_concepts",
"label": "yuuvis(R) Momentum Core Concepts",
"description": "Documentation for yuuvis(R) Momentum Core in a structured, theoretical way, with links to the tutorial section.",
"id": "ID_of_collection",
"owner": "OS",
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T11:05:17.166Z",
"source": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/-4BkAg",
"records": 2
},
"records": [
{
"collection": "ym_concepts",
"type": "article",
"title": "Schema - Defining Object Types",
"id": "ID_of_schema_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/AYFkAg",
"author": [
{
"name": "Heinrich Schuetzel"
},
{
"name": "George Trader"
},
{
"name": "Johann Fluss"
}
],
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T08:53:23.532Z"
},
{
"collection": "ym_concepts",
"type": "article",
"title": "Search Query Language",
"id": "ID_of_query_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/gIFkAg",
"author": [
{
"name": "Andrea Schumann"
},
{
"name": "Franz Lissner"
},
{
"name": "Hans Kammer"
},
{
"name": "Johann Fluss"
}
],
"created": "2020-06-16T14:03:01.833Z",
"modified": "2021-06-02T09:54:12.643Z"
}
]
}
}
}
}
]
} |
Search Queries
The individual sub-values within the JSON value for the property appBibjsonsample:bibjson
property are queryable.
>> Queries on Structured Data
In this chapter, some example search queries are explained.
Example 1
This query statement requests a search for all objects of type appBibjsonsample:medium
. The full set of metadata will be returned for each of them. In the example context of this tutorial, only two objects match the query: The book and the collection that were imported before.
Code Block |
---|
|
SELECT * FROM appBibjsonsample:medium |
Code Block |
---|
language | yml |
---|
title | request bodyRequest Body |
---|
linenumbers | true |
---|
collapse | true |
---|
|
{
"objects": [
{
"properties": {
"system:traceId": {
"value": "5681d3bddb4279de"
},
"system:objectTypeId": {
"value": "appBibjsonsample:medium"
},
"appBibjsonsample:bibjson": {
"value": {
"type": "book",
"title": "My Book Title",
"author": [
{
"name": "Heinrich Schuetzel"
},
{
"name": "Maximilian Sturz"
}
],
"year": "1995",
"owner": "My Library",
"id": "ID_of_book",
"url": "http://mylibrary.com/ebooks/36513466534",
"publisher": "Example Verlag Mustershagen",
"edition": {
"number": 2,
"language": "English"
},
"identifier": [
{
"id": "0002-9327",
"type": "issn"
}
]
}
},
"system:versionNumber": {
"value": 1
},
"system:createdBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:creationDate": {
"value": "2021-06-14T13:10:52.280Z"
},
"system:lastModificationDate": {
"value": "2021-06-14T13:10:52.280Z"
},
"system:baseTypeId": {
"value": "system:document"
},
"system:tenant": {
"value": "default"
},
"appBibjsonsample:locations": {
"value": [
"central library, CN-3214-5324",
"branch library east, 43-654b"
]
},
"system:lastModifiedBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:objectId": {
"value": "aab2b4d9-e829-45dd-981a-2f19a688592d"
}
}
},
{
"properties": {
"system:traceId": {
"value": "22839c5775801e9c"
},
"system:objectTypeId": {
"value": "appBibjsonsample:medium"
},
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"collection": "ym_concepts",
"label": "yuuvis(R) Momentum Core Concepts",
"description": "Documentation for yuuvis(R) Momentum Core in a structured, theoretical way, with links to the tutorial section.",
"id": "ID_of_collection",
"owner": "OS",
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T11:05:17.166Z",
"source": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/-4BkAg",
"records": 2
},
"records": [
{
"collection": "ym_concepts",
"type": "article",
"title": "Schema - Defining Object Types",
"id": "ID_of_schema_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/AYFkAg",
"author": [
{
"name": "Heinrich Schuetzel"
},
{
"name": "George Trader"
},
{
"name": "Johann Fluss"
}
],
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T08:53:23.532Z"
},
{
"collection": "ym_concepts",
"type": "article",
"title": "Search Query Language",
"id": "ID_of_query_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/gIFkAg",
"author": [
{
"name": "Andrea Schumann"
},
{
"name": "Franz Lissner"
},
{
"name": "Hans Kammer"
},
{
"name": "Johann Fluss"
}
],
"created": "2020-06-16T14:03:01.833Z",
"modified": "2021-06-02T09:54:12.643Z"
}
]
}
},
"system:lastModificationDate": {
"value": "2021-06-14T13:11:57.770Z"
},
"system:versionNumber": {
"value": 1
},
"system:baseTypeId": {
"value": "system:document"
},
"system:tenant": {
"value": "default"
},
"system:createdBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:creationDate": {
"value": "2021-06-14T13:11:57.770Z"
},
"system:lastModifiedBy": {
"value": "275c826c-6a61-4e89-9512-8d935a1631e5"
},
"system:objectId": {
"value": "3d4a67be-3341-4317-bb57-c48ea7ab0a1a"
}
}
}
],
"numItems": 2,
"hasMoreItems": false,
"totalNumItems": 2
} |
Example 2
In order to return only the bibliographic information in the result list of the search request, select the property appBibjsonsample:bibjsonbibjson
property.
Code Block |
---|
|
SELECT appBibjsonsample:bibjson FROM appBibjsonsample:medium |
Code Block |
---|
language | yml |
---|
title | response bodyRequest Body |
---|
linenumbers | true |
---|
collapse | true |
---|
|
{
"objects": [
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"type": "book",
"title": "My Book Title",
"author": [
{
"name": "Heinrich Schuetzel"
},
{
"name": "Maximilian Sturz"
}
],
"year": "1995",
"owner": "My Library",
"id": "ID_of_book",
"url": "http://mylibrary.com/ebooks/36513466534",
"publisher": "Example Verlag Mustershagen",
"edition": {
"number": 2,
"language": "English"
},
"identifier": [
{
"id": "0002-9327",
"type": "issn"
}
]
}
}
}
},
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"collection": "ym_concepts",
"label": "yuuvis(R) Momentum Core Concepts",
"description": "Documentation for yuuvis(R) Momentum Core in a structured, theoretical way, with links to the tutorial section.",
"id": "ID_of_collection",
"owner": "OS",
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T11:05:17.166Z",
"source": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/-4BkAg",
"records": 2
},
"records": [
{
"collection": "ym_concepts",
"type": "article",
"title": "Schema - Defining Object Types",
"id": "ID_of_schema_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/AYFkAg",
"author": [
{
"name": "Heinrich Schuetzel"
},
{
"name": "George Trader"
},
{
"name": "Johann Fluss"
}
],
"created": "2020-06-09T15:04:12.944Z",
"modified": "2021-06-10T08:53:23.532Z"
},
{
"collection": "ym_concepts",
"type": "article",
"title": "Search Query Language",
"id": "ID_of_query_article",
"link": "https://help.optimal-systems.com/yuuvis_develop/display/YMY/x/gIFkAg",
"author": [
{
"name": "Andrea Schumann"
},
{
"name": "Franz Lissner"
},
{
"name": "Hans Kammer"
},
{
"name": "Johann Fluss"
}
],
"created": "2020-06-16T14:03:01.833Z",
"modified": "2021-06-02T09:54:12.643Z"
}
]
}
}
}
}
],
"numItems": 2,
"hasMoreItems": false,
"totalNumItems": 2
} |
Example 3
It is even possible to return specified sub-values of the JSON structure stored in the property appBibjsonsample:bibjson
property. If you specify an index within a list, the values for the list elements with lower indices will be replaced by null
in the return statement as can be seen in line 9.
Code Block |
---|
|
SELECT appBibjsonsample:bibjson.title,appBibjsonsample:bibjson.author[1].name,appBibjsonsample:bibjson.metadata.id FROM appBibjsonsample:medium |
Code Block |
language |
---|
yml | title | response bodyRequest Body |
---|
linenumbers | true | collapse | true |
---|
|
{
"objects": [
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"title": "My Book Title",
"author": [
null,
{
"name": "Maximilian Sturz"
}
]
}
}
}
},
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"id": "ID_of_collection"
}
}
}
}
}
],
"numItems": 2,
"hasMoreItems": false,
"totalNumItems": 2
} |
Example 4
If you know the path of the sub-value within the JSON you want to query, you can directly specify it. The example query configures a search for a specific medium identified by its bibliographic ID.
Code Block |
---|
|
SELECT appBibjsonsample:bibjson.title FROM appBibjsonsample:medium WHERE appBibjsonsample:bibjson.id = 'ID_of_book' |
Code Block |
---|
languagetitle | ymlRequest Body |
---|
title | response body |
---|
linenumbers | true |
---|
collapse | linenumbers | true |
---|
|
{
"objects": [
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"title": "My Book Title",
"author": [
null,
{
"name": "Maximilian Sturz"
} "appBibjsonsample:bibjson": {
] "value": {
} "title": "My Book Title",
} } "author": [
}, { "properties": { null,
"appBibjsonsample:bibjson": { {
"value": { "metadataname": {"Maximilian Sturz"
"id": "ID_of_collection" }
}]
}
}
}
}
],
"numItems": 21,
"hasMoreItems": false,
"totalNumItems": 21
} |
Example 5
If you want to search for an object having with a specific a sub-value but the unknown path is unknown, a *
wildcard can be used. Each object containing the string ID_of_schema_article
as a sub-value for the property appBibjsonsample:bibjson
property will match the query.
Code Block |
---|
|
SELECT appBibjsonsample:bibjson.metadata.id FROM appBibjsonsample:medium WHERE appBibjsonsample:bibjson.* = 'ID_of_schema_article' |
Code Block |
---|
language | yml |
---|
title | response bodyRequest Body |
---|
linenumbers | true | collapse | true |
---|
|
{
"objects": [
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"id": "ID_of_collection"
}
}
}
}
}
],
"numItems": 1,
"hasMoreItems": false,
"totalNumItems": 1
} |
Example 6
The *
wildcard can also be used also instead of a specific index within a list. Thus, the condition will be checked for each list entry. Furthermore, full-text search with CONTAINS is possible in case of string sub-values.
Code Block |
---|
|
SELECT appBibjsonsample:bibjson.title FROM appBibjsonsample:medium WHERE appBibjsonsample:bibjson.author[*].name CONTAINS('Sturz') |
Code Block |
---|
language | yml |
---|
title | response bodyRequest Body |
---|
linenumbers | true |
---|
collapse | true |
---|
|
{
"objects": [
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"title": "My Book Title"
}
}
}
}
],
"numItems": 1,
"hasMoreItems": false,
"totalNumItems": 1
} |
Example 7
Use ..
in order to replace unknown parts of a path. The query below specifies a search for objects where the property appBibjsonsample:bibjson
contains property contains Schuetzel
in the value for the key author[*].name
that key which can be located at any hierarchical level within the JSON. Furthermore, only only only key-value mappings for keys named id
will be displayed in the response body.
Code Block |
---|
|
SELECT appBibjsonsample:bibjson..id FROM appBibjsonsample:medium WHERE appBibjsonsample:bibjson..author[*].name CONTAINS('Schuetzel') |
Code Block |
---|
language | yml |
---|
title | response bodyRequest Body |
---|
linenumbers | true | collapse | true |
---|
|
{
"objects": [
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"id": "ID_of_book",
"identifier": [
{
"id": "0002-9327"
}
]
}
}
}
},
{
"properties": {
"appBibjsonsample:bibjson": {
"value": {
"metadata": {
"id": "ID_of_collection"
},
"records": [
{
"id": "ID_of_schema_article"
},
{
"id": "ID_of_query_article"
}
]
}
}
}
}
],
"numItems": 2,
"hasMoreItems": false,
"totalNumItems": 2
} |
Summary
The property structureddata
property type structureddata
allows allows for the storage of interleaved data structures in a queryable way without defining each single sub-property in the schema. This tutorial gave some explanations on how to define such a property in the schema, how to set a value during an object creation and how to address the individual sub-values in search queries, in the example context of a library.
>> Code examples in gitHubGitHub
Info |
---|
|
Read on
Section |
---|
Column |
---|
| Insert excerpt |
---|
| Managing the Schema |
---|
| Managing the Schema |
---|
nopanel | true |
---|
| Keep reading
|
Column |
---|
| Insert excerpt |
---|
| Importing Documents via Core API |
---|
| Importing Documents via Core API |
---|
nopanel | true |
---|
| Keep reading
|
Column |
---|
| Insert excerpt |
---|
| Search Query Language |
---|
| Search Query Language |
---|
nopanel | true |
---|
| Keep reading
|
|
|
...