Hi,

The idea here is to be able to output a MongoDB collection content as complex features.

For those wondering, how MongoDB store works right now, it basically flats the JSON elements and ignore collections (geometries are treated as special case and properly encoded).

Consider that we have in a MongoDB a collection called stations that contains the measurements
of several meteorological stations:

   db.stations.insert({
      "id": "1",
      "geometry": {
          "coordinates": [
              50.0,
              60.0
          ],
          "type": "Point"
      },
      "name": "station 1",
      "contact": {
        "mail": "stati...@mail.com"
      },
      "measurements": [
          {
              "name": "temp",
              "unit": "c",
              "value": 35.5
          },
          {
              "name": "wind",
              "unit": "km/h",
              "value": 110.5
          }
      ]
   })

   db.stations.createIndex({
      geometry: "2dsphere"
   })

The current MongoDB store will output something like this for a GetFeature request:

   <?xml version="1.0" encoding="UTF-8"?>
   <wfs:FeatureCollection xmlns="http://www.opengis.net/wfs";
   xmlns:gml="http://www.opengis.net/gml"; xmlns:mongo="mongo"
   xmlns:wfs="http://www.opengis.net/wfs";
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
   xsi:schemaLocation="mongo
   
http://localhost:8092/geoserver/mongo/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=mongo%3Astations3
   http://www.opengis.net/wfs
   http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd";>
        <gml:boundedBy>
            <gml:null>unknown</gml:null>
        </gml:boundedBy>
        <gml:featureMember>
            <mongo:stations3 fid="580f7cb4c1ed909ae180819a">
                <mongo:geometry>
                    <gml:Point
   srsName="http://www.opengis.net/gml/srs/epsg.xml#4326";>
                        <gml:coordinates cs="," decimal="." ts=" "
   xmlns:gml="http://www.opengis.net/gml";>10,60</gml:coordinates>
                    </gml:Point>
                </mongo:geometry>
                <mongo:id>1</mongo:id>
                <gml:name>station 1</gml:name>
   <mongo:contact.mail>stati...@mail.com</mongo:contact.mail>
            </mongo:stations3>
        </gml:featureMember>
   </wfs:FeatureCollection>

As you can see the the list of measurements was ignored and the JSON attributes were flatted (contact.mail).

If MongoDB stations collection was encoded as complex features the result should have been something similar to this instead:

   <?xml version="1.0" encoding="UTF-8"?>
   <wfs:FeatureCollection ...>
        <st:featureMember>
            <st:StationFeature gml:id="1">
                <st:name>station 1</st:name>
                <st:contact>
                    <st:mail>stati...@mail.com</st:mail>
                </st:contact>
                <st:measurement>
                    <st:name>temp</st:name>
                    <st:unit>c</st:unit>
                    <st:value>35.5</st:value>
                </st:measurement>
                <st:measurement>
                    <st:name>wind</st:name>
                    <st:unit>km/h</st:unit>
                    <st:value>110.5</st:value>
                </st:measurement>
                <st:geometry>
                    <gml:Point
   srsName="http://www.opengis.net/gml/srs/epsg.xml#4326";>
   <gml:coordinates>50.0,60.0</gml:coordinates>
                    </gml:Point>
                </st:geometry>
            </st:StationFeature>
        </gml:featureMember>
   </wfs:FeatureCollection>

The associated schema was attached to this mail.

App-schema can work with simple stores creating complex features by composing several simple features, in the case of MongoDB we actually want to be able to map the complete JSON tree. This is the main reason why MongoDB current store will not work with app-schema, we would only have access to the flat attributes.

The idea were would be to create a complex MongoDB store capable to answer app-schema queries by having access to all the JSON object, this store will only be usable by app-schema and cannot be used in a standalone way. This way we will reuse all app-schema already implemented machinery and avoid to duplicate a lot of complex code.

I already perform some tests and was able to get complex features with simple mappings:

    <typeMappings>
        <FeatureTypeMapping>
<sourceDataStore>data_source</sourceDataStore>
            <sourceType>st</sourceType>
<targetElement>st:StationFeature</targetElement>
            <attributeMappings>
                <AttributeMapping>
                    <targetAttribute>
                        st:StationFeature
                    </targetAttribute>
                    <idExpression>
<OCQL>jsonSelect("stations.id")</OCQL>
                    </idExpression>
                </AttributeMapping>
                <AttributeMapping>
<targetAttribute>st:name</targetAttribute>
                    <sourceExpression>
<OCQL>jsonSelect("stations.name")</OCQL>
                    </sourceExpression>
                </AttributeMapping>
                <AttributeMapping>
<targetAttribute>st:contact/st:mail</targetAttribute>
                    <sourceExpression>
<OCQL>jsonSelect("stations.contact.mail")</OCQL>
                    </sourceExpression>
                    <isMultiple>true</isMultiple>
                </AttributeMapping>
            </attributeMappings>
        </FeatureTypeMapping>
    </typeMappings>

In this example I used a filter function for explicitly select the deep JSON content.

The most difficult part is the mapping of the JSON lists as nested objects through feature chaining, the way I found to do it right now is to use a filter function that tell
explicitly the path of the sub-collection:

   <AttributeMapping>
        <targetAttribute>st:measurement</targetAttribute>
        <sourceExpression>
            <OCQL>jsonSelectCollection("stations.id",
   "stations.measurement")</OCQL>
   <linkElement>st:SituationMeasurement</linkElement>
            <linkField>FEATURE_LINK[1]</linkField>
        </sourceExpression>
        <isMultiple>true</isMultiple>
   </AttributeMapping>

When performing a query we visit the filter I to see if we can found the explicit sub collection.

With this approach we will have a strange MongoDB complex store that only makes sense to use with app-schema but we will reuse app-schema machinery and all this work will be contained in
a single module.

Opinions on this are very welcome, I know that this is a lot to digest and the subject is a little bit complex :)

Regards,

Nuno Oliveira

--
==
GeoServer Professional Services from the experts!
Visit http://goo.gl/it488V for more information.
==
Nuno Miguel Carvalho Oliveira
@nmcoliveira
Software Engineer

GeoSolutions S.A.S.
Via di Montramito 3/A
55054  Massarosa (LU)
Italy

phone: +39 0584 962313
fax:   +39 0584 1660272
mob:   +39  333 8128928

http://www.geo-solutions.it
http://twitter.com/geosolutions_it

-------------------------------------------------------

AVVERTENZE AI SENSI DEL D.Lgs. 196/2003
Le informazioni contenute in questo messaggio di posta elettronica e/o nel/i 
file/s allegato/i sono
da considerarsi strettamente riservate. Il loro utilizzo è consentito 
esclusivamente al destinatario del messaggio, per le finalità indicate
nel messaggio stesso. Qualora riceviate questo messaggio senza esserne il 
destinatario, Vi preghiamo cortesemente di darcene notizia via e
-mail e di procedere alla distruzione del messaggio stesso, cancellandolo dal 
Vostro sistema. Conservare il messaggio stesso, divulgarlo
anche in parte, distribuirlo ad altri soggetti, copiarlo, od utilizzarlo per 
finalità diverse, costituisce comportamento contrario ai
principi dettati dal D.Lgs. 196/2003.
The information in this message and/or attachments, is intended solely for the attention and use of
the named addressee(s) and may be confidential or proprietary in nature or 
covered by the provisions of privacy act (Legislative Decree
June, 30 2003, no.196 - Italy's New Data Protection Code).Any use not in accord 
with its purpose, any disclosure, reproduction, copying,
distribution, or either dissemination, either whole or partial, is strictly 
forbidden except previous formal approval of the named
addressee(s). If you are not the intended recipient, please contact immediately 
the sender by telephone, fax or e-mail and delete the
information in this message that has been received in error. The sender does 
not give any warranty or accept liability as the content,
accuracy or completeness of sent messages and accepts no responsibility  for 
changes made after they were sent or for other risks which
arise as a result of e-mail transmission, viruses, etc.

Attachment: stations.xsd
Description: XML document

------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive. 
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
_______________________________________________
GeoTools-Devel mailing list
GeoTools-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to