mongo-tutorial.rst 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. .. _mongo_tutorial:
  2. MongoDB Tutorial
  3. ================
  4. 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.
  5. Use Case
  6. --------
  7. 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.
  8. First of all let's insert some test data in a MongoDB data store:
  9. .. code-block:: javascript
  10. db.stations.insert({
  11. "id": "1",
  12. "name": "station 1",
  13. "contact": {
  14. "mail": "station1@mail.com"
  15. },
  16. "geometry": {
  17. "coordinates": [
  18. 50,
  19. 60
  20. ],
  21. "type": "Point"
  22. },
  23. "measurements": [
  24. {
  25. "name": "temp",
  26. "unit": "c",
  27. "values": [
  28. {
  29. "time": 1482146800,
  30. "value": 20
  31. }
  32. ]
  33. },
  34. {
  35. "name": "wind",
  36. "unit": "km/h",
  37. "values": [
  38. {
  39. "time": 1482146833,
  40. "value": 155
  41. }
  42. ]
  43. }
  44. ]
  45. })
  46. db.stations.insert({
  47. "id": "2",
  48. "name": "station 2",
  49. "contact": {
  50. "mail": "station2@mail.com"
  51. },
  52. "geometry": {
  53. "coordinates": [
  54. 100,
  55. -50
  56. ],
  57. "type": "Point"
  58. },
  59. "measurements": [
  60. {
  61. "name": "temp",
  62. "unit": "c",
  63. "values": [
  64. {
  65. "time": 1482146911,
  66. "value": 35
  67. },
  68. {
  69. "time": 1482146935,
  70. "value": 25
  71. }
  72. ]
  73. },
  74. {
  75. "name": "wind",
  76. "unit": "km/h",
  77. "values": [
  78. {
  79. "time": 1482146964,
  80. "value": 80
  81. }
  82. ]
  83. },
  84. {
  85. "name": "pression",
  86. "unit": "pa",
  87. "values": [
  88. {
  89. "time": 1482147026,
  90. "value": 1019
  91. },
  92. {
  93. "time": 1482147051,
  94. "value": 1015
  95. }
  96. ]
  97. }
  98. ]
  99. })
  100. db.stations.createIndex({
  101. "geometry": "2dsphere"
  102. })
  103. This is the schema that will be used to do the mappings in app-schema:
  104. .. code-block:: xml
  105. <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  106. xmlns:gml="http://www.opengis.net/gml"
  107. xmlns:st="http://www.stations.org/1.0"
  108. targetNamespace="http://www.stations.org/1.0"
  109. elementFormDefault="qualified" attributeFormDefault="unqualified">
  110. <xs:import namespace="http://www.opengis.net/gml"
  111. schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
  112. <xs:complexType name="ContactType">
  113. <xs:sequence>
  114. <xs:element name="mail" minOccurs="0" maxOccurs="1" type="xs:string"/>
  115. </xs:sequence>
  116. </xs:complexType>
  117. <xs:complexType name="MeasurementPropertyType">
  118. <xs:sequence minOccurs="0">
  119. <xs:element ref="st:Measurement"/>
  120. </xs:sequence>
  121. <xs:attributeGroup ref="gml:AssociationAttributeGroup"/>
  122. </xs:complexType>
  123. <xs:complexType name="MeasurementType" abstract="true">
  124. <xs:sequence>
  125. <xs:element name="name" minOccurs="1" maxOccurs="1" type="xs:string"/>
  126. <xs:element name="unit" minOccurs="1" maxOccurs="1" type="xs:string"/>
  127. <xs:element name="values" minOccurs="1" maxOccurs="unbounded" type="st:ValuePropertyType"/>
  128. </xs:sequence>
  129. </xs:complexType>
  130. <xs:complexType name="ValuePropertyType">
  131. <xs:sequence minOccurs="0">
  132. <xs:element ref="st:Value"/>
  133. </xs:sequence>
  134. <xs:attributeGroup ref="gml:AssociationAttributeGroup"/>
  135. </xs:complexType>
  136. <xs:complexType name="ValueType">
  137. <xs:sequence>
  138. <xs:element name="timestamp" minOccurs="1" maxOccurs="1" type="xs:long"/>
  139. <xs:element name="value" minOccurs="1" maxOccurs="1" type="xs:double"/>
  140. </xs:sequence>
  141. </xs:complexType>
  142. <xs:complexType name="StationFeatureType">
  143. <xs:complexContent>
  144. <xs:extension base="gml:AbstractFeatureType">
  145. <xs:sequence>
  146. <xs:element name="name" minOccurs="1" maxOccurs="1" type="xs:string"/>
  147. <xs:element name="contact" minOccurs="0" maxOccurs="1" type="st:ContactType"/>
  148. <xs:element name="measurement" minOccurs="0" maxOccurs="unbounded" type="st:MeasurementPropertyType"/>
  149. <xs:element name="geometry" type="gml:GeometryPropertyType" minOccurs="0" maxOccurs="1"/>
  150. </xs:sequence>
  151. </xs:extension>
  152. </xs:complexContent>
  153. </xs:complexType>
  154. <xs:element name="StationFeature" type="st:StationFeatureType" substitutionGroup="gml:_Feature"/>
  155. <xs:element name="Measurement" type="st:MeasurementType" substitutionGroup="gml:_Feature"/>
  156. <xs:element name="Value" type="st:ValueType" substitutionGroup="gml:_Feature"/>
  157. </xs:schema>
  158. Mappings
  159. --------
  160. MongoDB Store
  161. ^^^^^^^^^^^^^
  162. When configuring app-schema mappings for a MongoDB source some connection parameters tweaks might be needed, in order to ensure that the full set of recognized and made available to the mapping.
  163. The setup of a MongoDB Store implies the creation of a Mongo schema, inferred from the db collection.
  164. This process by default will use a random Mongo object from the collection. If that object doesn't contain all attributes of interest, the result will be an incomplete schema.
  165. This behaviour can thus be controlled by means of the following two parameters, which should be provided inside the ``<parameters>`` element under the ``<DataStore>`` node:
  166. * ``objs_id_schema``, which specifies a comma separated list of MongoDB JSON object to be used to build the schema (not needed if ``max_objs_schema`` is present).
  167. .. code-block:: xml
  168. <Parameter>
  169. <name>objs_id_schema</name>
  170. <value>6eb85d889396eb0475f815ef,6eb85d889396eb0475f815eg</value>
  171. </Parameter>
  172. * ``max_objs_schema``, which specifies the max number of MongoDB JSON object to be used to build the schema and where a value of ``-1`` means all the objects present in the collection (not needed if ``objs_id_schema`` is present).
  173. .. code-block:: xml
  174. <Parameter>
  175. <name>max_objs_schema</name>
  176. <value>-1</value>
  177. </Parameter>
  178. Both parameters can also be specified via the REST API, see :ref:`Cleaning schemas on internal MongoDB stores <rest_App-Schema>` for more details.
  179. Nested elements
  180. ^^^^^^^^^^^^^^^
  181. 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:
  182. .. list-table::
  183. :widths: 20 30 50
  184. * - **Function**
  185. - **Example**
  186. - **Description**
  187. * - jsonSelect
  188. - jsonSelect('contact.mail')
  189. - Used to retrieve the value for the mapping from a MongoDB object.
  190. * - collectionLink
  191. - collectionLink('measurements.values')
  192. - Used when chaining entities with a nested collection.
  193. * - collectionId
  194. - collectionId()
  195. - Instructs the mapper to generate a ID for the nested collection.
  196. * - nestedCollectionLink
  197. - nestedCollectionLink()
  198. - Used on the nested collection to create a link with the parent feature.
  199. Mappings file example
  200. ^^^^^^^^^^^^^^^^^^^^^
  201. 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.
  202. Follows a the complete mappings file:
  203. .. code-block:: xml
  204. <?xml version="1.0" encoding="UTF-8"?>
  205. <as:AppSchemaDataAccess xmlns:as="http://www.geotools.org/app-schema"
  206. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  207. xsi:schemaLocation="http://www.geotools.org/app-schema AppSchemaDataAccess.xsd">
  208. <namespaces>
  209. <Namespace>
  210. <prefix>st</prefix>
  211. <uri>http://www.stations.org/1.0</uri>
  212. </Namespace>
  213. <Namespace>
  214. <prefix>gml</prefix>
  215. <uri>http://www.opengis.net/gml</uri>
  216. </Namespace>
  217. </namespaces>
  218. <sourceDataStores>
  219. <DataStore>
  220. <id>data_source</id>
  221. <parameters>
  222. <Parameter>
  223. <name>data_store</name>
  224. <value>mongodb://{mongoHost}:{mongoPort}/{dataBaseName}</value>
  225. </Parameter>
  226. <Parameter>
  227. <name>namespace</name>
  228. <value>http://www.stations.org/1.0</value>
  229. </Parameter>
  230. <Parameter>
  231. <name>schema_store</name>
  232. <value>file:{schemaStore}</value>
  233. </Parameter>
  234. <Parameter>
  235. <name>data_store_type</name>
  236. <value>complex</value>
  237. </Parameter>
  238. <Parameter>
  239. <name>max_objs_schema</name>
  240. <value>-1</value>
  241. </Parameter>
  242. </parameters>
  243. </DataStore>
  244. </sourceDataStores>
  245. <targetTypes>
  246. <FeatureType>
  247. <schemaUri>stations.xsd</schemaUri>
  248. </FeatureType>
  249. </targetTypes>
  250. <typeMappings>
  251. <FeatureTypeMapping>
  252. <sourceDataStore>data_source</sourceDataStore>
  253. <sourceType>{collectionName}</sourceType>
  254. <targetElement>st:StationFeature</targetElement>
  255. <attributeMappings>
  256. <AttributeMapping>
  257. <targetAttribute>st:StationFeature</targetAttribute>
  258. <idExpression>
  259. <OCQL>jsonSelect('id')</OCQL>
  260. </idExpression>
  261. </AttributeMapping>
  262. <AttributeMapping>
  263. <targetAttribute>st:name</targetAttribute>
  264. <sourceExpression>
  265. <OCQL>jsonSelect('name')</OCQL>
  266. </sourceExpression>
  267. </AttributeMapping>
  268. <AttributeMapping>
  269. <targetAttribute>st:contact/st:mail</targetAttribute>
  270. <sourceExpression>
  271. <OCQL>jsonSelect('contact.mail')</OCQL>
  272. </sourceExpression>
  273. </AttributeMapping>
  274. <AttributeMapping>
  275. <targetAttribute>st:measurement</targetAttribute>
  276. <sourceExpression>
  277. <OCQL>collectionLink('measurements')</OCQL>
  278. <linkElement>aaa</linkElement>
  279. <linkField>FEATURE_LINK[1]</linkField>
  280. </sourceExpression>
  281. <isMultiple>true</isMultiple>
  282. </AttributeMapping>
  283. <AttributeMapping>
  284. <targetAttribute>st:geometry</targetAttribute>
  285. <sourceExpression>
  286. <OCQL>jsonSelect('geometry')</OCQL>
  287. </sourceExpression>
  288. </AttributeMapping>
  289. </attributeMappings>
  290. </FeatureTypeMapping>
  291. <FeatureTypeMapping>
  292. <sourceDataStore>data_source</sourceDataStore>
  293. <sourceType>{collectionName}</sourceType>
  294. <mappingName>aaa</mappingName>
  295. <targetElement>st:Measurement</targetElement>
  296. <attributeMappings>
  297. <AttributeMapping>
  298. <targetAttribute>st:Measurement</targetAttribute>
  299. <idExpression>
  300. <OCQL>collectionId()</OCQL>
  301. </idExpression>
  302. </AttributeMapping>
  303. <AttributeMapping>
  304. <targetAttribute>st:name</targetAttribute>
  305. <sourceExpression>
  306. <OCQL>jsonSelect('name')</OCQL>
  307. </sourceExpression>
  308. </AttributeMapping>
  309. <AttributeMapping>
  310. <targetAttribute>st:unit</targetAttribute>
  311. <sourceExpression>
  312. <OCQL>jsonSelect('unit')</OCQL>
  313. </sourceExpression>
  314. </AttributeMapping>
  315. <AttributeMapping>
  316. <targetAttribute>st:values</targetAttribute>
  317. <sourceExpression>
  318. <OCQL>collectionLink('values')</OCQL>
  319. <linkElement>st:Value</linkElement>
  320. <linkField>FEATURE_LINK[2]</linkField>
  321. </sourceExpression>
  322. <isMultiple>true</isMultiple>
  323. </AttributeMapping>
  324. <AttributeMapping>
  325. <targetAttribute>FEATURE_LINK[1]</targetAttribute>
  326. <sourceExpression>
  327. <OCQL>nestedCollectionLink()</OCQL>
  328. </sourceExpression>
  329. </AttributeMapping>
  330. </attributeMappings>
  331. </FeatureTypeMapping>
  332. <FeatureTypeMapping>
  333. <sourceDataStore>data_source</sourceDataStore>
  334. <sourceType>{collectionName}</sourceType>
  335. <targetElement>st:Value</targetElement>
  336. <attributeMappings>
  337. <AttributeMapping>
  338. <targetAttribute>st:Value</targetAttribute>
  339. <idExpression>
  340. <OCQL>collectionId()</OCQL>
  341. </idExpression>
  342. </AttributeMapping>
  343. <AttributeMapping>
  344. <targetAttribute>st:timestamp</targetAttribute>
  345. <sourceExpression>
  346. <OCQL>jsonSelect('time')</OCQL>
  347. </sourceExpression>
  348. </AttributeMapping>
  349. <AttributeMapping>
  350. <targetAttribute>st:value</targetAttribute>
  351. <sourceExpression>
  352. <OCQL>jsonSelect('value')</OCQL>
  353. </sourceExpression>
  354. </AttributeMapping>
  355. <AttributeMapping>
  356. <targetAttribute>FEATURE_LINK[2]</targetAttribute>
  357. <sourceExpression>
  358. <OCQL>nestedCollectionLink()</OCQL>
  359. </sourceExpression>
  360. </AttributeMapping>
  361. </attributeMappings>
  362. </FeatureTypeMapping>
  363. </typeMappings>
  364. </as:AppSchemaDataAccess>
  365. The mappings for the attributes are straightforward, for example the following mapping:
  366. .. code-block:: xml
  367. <AttributeMapping>
  368. <targetAttribute>st:contact/st:mail</targetAttribute>
  369. <sourceExpression>
  370. <OCQL>jsonSelect('contact.mail')</OCQL>
  371. </sourceExpression>
  372. </AttributeMapping>
  373. 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``.
  374. 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:
  375. .. code-block:: xml
  376. <AttributeMapping>
  377. <targetAttribute>st:measurement</targetAttribute>
  378. <sourceExpression>
  379. <OCQL>collectionLink('measurements')</OCQL>
  380. <linkElement>st:Measurement</linkElement>
  381. <linkField>FEATURE_LINK[1]</linkField>
  382. </sourceExpression>
  383. <isMultiple>true</isMultiple>
  384. </AttributeMapping>
  385. and in the ``Measurement`` feature type the link to the parent feature is defined with the following mapping:
  386. .. code-block:: xml
  387. <AttributeMapping>
  388. <targetAttribute>FEATURE_LINK[1]</targetAttribute>
  389. <sourceExpression>
  390. <OCQL>nestedCollectionLink()</OCQL>
  391. </sourceExpression>
  392. </AttributeMapping>
  393. 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.
  394. Querying
  395. --------
  396. To create an MongoDB app-schema layer in GeoServer, the app-schema extension and the mongo-complex extension needs to be installed.
  397. 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.
  398. 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``.
  399. Is possible to query with WFS complex features encoded in GML and GeoJson using complex features filtering capabilities.
  400. For example, querying all the stations that have a measurement value with a time stamp superior to ``1482146964``:
  401. .. code-block:: xml
  402. <wfs:Query typeName="st:StationFeature">
  403. <ogc:Filter>
  404. <ogc:Filter>
  405. <ogc:PropertyIsGreaterThan>
  406. <ogc:PropertyName>
  407. st:StationFeature/st:measurement/st:values/st:timestamp
  408. </ogc:PropertyName>
  409. <ogc:Literal>
  410. 1482146964
  411. </ogc:Literal>
  412. </ogc:PropertyIsGreaterThan>
  413. </ogc:Filter>
  414. </ogc:Filter>
  415. </wfs:Query>