.. _mongo_tutorial:
MongoDB Tutorial
================
This tutorial demonstrates how to use app-schema plugin with a MongoDB data store. This tutorial will focus on the MongoDB data store specificities is highly recommended to read the app-schema documentation before.
Use Case
--------
The use case for this tutorial will be to serve through app-schema the information about some meteorological stations stored in a MongoDB database. Note that this use case is completely fictional and only used to demonstrate the MongoDB and app-schema integration.
First of all let's insert some test data in a MongoDB data store:
.. code-block:: json
db.stations.insert({
"id": "1",
"name": "station 1",
"contact": {
"mail": "station1@mail.com"
},
"geometry": {
"coordinates": [
50,
60
],
"type": "Point"
},
"measurements": [
{
"name": "temp",
"unit": "c",
"values": [
{
"time": 1482146800,
"value": 20
}
]
},
{
"name": "wind",
"unit": "km/h",
"values": [
{
"time": 1482146833,
"value": 155
}
]
}
]
})
db.stations.insert({
"id": "2",
"name": "station 2",
"contact": {
"mail": "station2@mail.com"
},
"geometry": {
"coordinates": [
100,
-50
],
"type": "Point"
},
"measurements": [
{
"name": "temp",
"unit": "c",
"values": [
{
"time": 1482146911,
"value": 35
},
{
"time": 1482146935,
"value": 25
}
]
},
{
"name": "wind",
"unit": "km/h",
"values": [
{
"time": 1482146964,
"value": 80
}
]
},
{
"name": "pression",
"unit": "pa",
"values": [
{
"time": 1482147026,
"value": 1019
},
{
"time": 1482147051,
"value": 1015
}
]
}
]
})
db.stations.createIndex({
"geometry": "2dsphere"
})
This is the schema that will be used to do the mappings in app-schema:
.. code-block:: xml
Mappings
--------
MongoDB objects may contain nested elements and nested collections. The following three functions make possible to select nested elements and link nested collections using a JSON path:
.. list-table::
:widths: 20 30 50
* - **Function**
- **Example**
- **Description**
* - jsonSelect
- jsonSelect('contact.mail')
- Used to retrieve the value for the mapping from a MongoDB object.
* - collectionLink
- collectionLink('measurements.values')
- Used when chaining entities with a nested collection.
* - collectionId
- collectionId()
- Instructs the mapper to generate a ID for the nested collection.
* - nestedCollectionLink
- nestedCollectionLink()
- Used on the nested collection to create a link with the parent feature.
A station data is composed of some meta-information about the station and a list of measurements. Each measurement as some meta-information and contains a list of values. The mappings will contain three top entities: the station, the measurements and the values.
Follows a the complete mappings file:
.. code-block:: xml
st
http://www.stations.org/1.0
gml
http://www.opengis.net/gml
data_source
data_store
mongodb://{mongoHost}:{mongoPort}/{dataBaseName}
namespace
http://www.stations.org/1.0
schema_store
file:{schemaStore}
data_store_type
complex
stations.xsd
data_source
{collectionName}
st:StationFeature
st:StationFeature
jsonSelect('id')
st:name
jsonSelect('name')
st:contact/st:mail
jsonSelect('contact.mail')
st:measurement
collectionLink('measurements')
aaa
FEATURE_LINK[1]
true
st:geometry
jsonSelect('geometry')
data_source
{collectionName}
aaa
st:Measurement
st:Measurement
collectionId()
st:name
jsonSelect('name')
st:unit
jsonSelect('unit')
st:values
collectionLink('values')
st:Value
FEATURE_LINK[2]
true
FEATURE_LINK[1]
nestedCollectionLink()
data_source
{collectionName}
st:Value
st:Value
collectionId()
st:timestamp
jsonSelect('time')
st:value
jsonSelect('value')
FEATURE_LINK[2]
nestedCollectionLink()
The mappings for the attributes are straightforward, for example the following mapping:
.. code-block:: xml
st:contact/st:mail
jsonSelect('contact.mail')
The mapping above defines that the contact mail for a station will be available at the JSON path ``contact.mail`` and that the correspondent XML schema element is the XPATH ``st:contact/st:mail``.
The feature chaining is a little bit more complex. Let's take as an example the chaining between ``StationFeature`` and ``Measurement`` features. In the ``StationFeature`` feature type the link to the Measurement entity is defined with the following mapping:
.. code-block:: xml
st:measurement
collectionLink('measurements')
st:Measurement
FEATURE_LINK[1]
true
and in the ``Measurement`` feature type the link to the parent feature is defined with the following mapping:
.. code-block:: xml
FEATURE_LINK[1]
nestedCollectionLink()
With the two mapping above we tie the two features types together. When working with a MongoDB data store this mappings will always be petty much the same, only the nested collection path and the feature link index need to be updated. Note that the JSON path of the nested collections attributes are relative to the parent.
Querying
--------
To create an MongoDB app-schema layer in GeoServer, the app-schema extension and the mongo-complex extension needs to be installed.
A workspace for each name space declared in the mappings file needs to be created, in this case the workspace ``st`` with URI ``http://www.stations.org/1.0`` needs to be created. No need to create a ``gml`` workspace.
Creating a MongoDB app-schema layer is similar to any other app-schema layer, just create an app-schema store pointing to the correct mappings file and select the layer correspondent to the top entity, in this case ``st:StationFeature``.
Is possible to query with WFS complex features encoded in GML and GeoJson using complex features filtering capabilities.
For example, querying all the stations that have a measurement value with a time stamp superior to ``1482146964``:
.. code-block:: xml
st:StationFeature/st:measurement/st:values/st:timestamp
1482146964