MongoDB教程
本教程演示了如何将app-schema插件与MongoDB数据存储一起使用。本教程将重点介绍MongoDB数据存储的特性,强烈建议您先阅读app-schema文档。
用例
本教程的用例是通过app-schema提供有关存储在MongoDB数据库中的某些气象站的信息。请注意,此用例完全是虚构的,仅用于演示MongoDB和app-schema集成。
首先,让我们在MongoDB数据存储中插入一些测试数据:
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" })
这是将用于在app-schema中执行映射的模式:
<xs:schema version = “1.0” xmlns:xs = “http://www.w3.org/2001/XMLSchema” xmlns:gml = “http://www.opengis.net/gml” xmlns:st = “ http://www.stations.org/1.0“targetNamespace = ”http://www.stations.org/1.0“ elementFormDefault = ”qualified“ attributeFormDefault = ”unqualified“ > <xs:import namespace = ”http:// www .opengis.net / gml“ schemaLocation = ”http://schemas.opengis.net/gml/3.2.1/gml.xsd“ /> <xs:complexType name = ”ContactType“ > <xs:sequence> <xs:element name = “mail” minOccurs =“0” maxOccurs = “1” type = “xs:string” /> </ xs:sequence> </ xs:complexType> <xs:complexType name = “MeasurementPropertyType” > <xs:sequence minOccurs = “0” > < xs:element ref = “st:Measurement” /> </ xs:sequence> <xs:attributeGroup ref = “gml:AssociationAttributeGroup” /> </ xs:complexType> <xs:complexType name = “MeasurementType” abstract = “true “ > <xs:sequence> <xs:element name = “name” minOccurs = “1” maxOccurs = “1” type = “xs:string” /> <xs:element name = “unit” minOccurs = “1” maxOccurs = “1” type = “xs:string” /> <xs:element name = “values “ minOccurs = ”1“ maxOccurs = ”unbounded“ type = ”st:ValuePropertyType“ /> </ xs:sequence> </ xs:complexType> <xs:complexType name = ”ValuePropertyType“ > <xs:sequence minOccurs = ”0 “ > <xs:element ref = “st:Value” /> </ xs:sequence> <xs:attributeGroup ref = “gml:AssociationAttributeGroup” /> </ xs:complexType> <xs:complexType name = “ValueType” > <xs:sequence> <xs:element name = “timestamp” minOccurs = “1” maxOccurs = “1” type = “xs:long” /> <xs:element name = “value” minOccurs = “1” maxOccurs = “1” type = “xs:double” /> </ xs:sequence> </ xs: complexType> <xs:complexType name = “StationFeatureType” > <xs:complexContent> <xs:extension base = “gml:AbstractFeatureType” > <xs:sequence> <xs:element name = “name” minOccurs = “1” maxOccurs = “1” type = “xs:string” /> <xs:element name = “contact” minOccurs = “0” maxOccurs = “1” type = “st:ContactType” /> <xs:element name = “measurement” minOccurs = “0” maxOccurs = “unbounded” type = “st:MeasurementPropertyType” /> <xs:element name = “geometry” type = “gml:GeometryPropertyType” minOccurs = “0” maxOccurs = “1” /> </ xs:sequence> </ xs:extension> </ xs:complexContent> </ xs:complexType> <xs:element name = “StationFeature” type = “st: StationFeatureType“ substitutionGroup = ”gml:_Feature“ /> <xs:element name = ”Measurement“ type = ”st:MeasurementType“ substitutionGroup = ”gml:_Feature“ /> <xs:element name = ”Value“ type = ”st: ValueType“ substitutionGroup = ”gml:_Feature“ /> </ xs:schema>
映射
MongoDB对象可能包含嵌套元素和嵌套集合。以下三个函数可以使用JSON路径选择嵌套元素和链接嵌套集合:
功能 | 例 | 描述 |
jsonSelect | jsonSelect( 'contact.mail') | 用于从MongoDB对象检索映射的值。 |
collectionLink | collectionLink( 'measurements.values') | 在使用嵌套集合链接实体时使用。 |
collectionId | collectionId() | 指示映射器为嵌套集合生成ID。 |
nestedCollectionLink | nestedCollectionLink() | 在嵌套集合上使用,以创建与父功能的链接。 |
站数据由关于站的一些元信息和测量列表组成。每个测量都作为一些元信息并包含一个值列表。映射将包含三个顶部实体:工作站,测量值和值。
遵循完整的映射文件:
<?xml version="1.0" encoding="UTF-8"?> <as:AppSchemaDataAccess xmlns:as="http://www.geotools.org/app-schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.geotools.org/app-schema AppSchemaDataAccess.xsd"> <namespaces> <Namespace> <prefix>st</prefix> <uri>http://www.stations.org/1.0</uri> </Namespace> <Namespace> <prefix>gml</prefix> <uri>http://www.opengis.net/gml</uri> </Namespace> </namespaces> <sourceDataStores> <DataStore> <id>data_source</id> <parameters> <Parameter> <name>data_store</name> <value>mongodb://{mongoHost}:{mongoPort}/{dataBaseName}</value> </Parameter> <Parameter> <name>namespace</name> <value>http://www.stations.org/1.0</value> </Parameter> <Parameter> <name>schema_store</name> <value>file:{schemaStore}</value> </Parameter> <Parameter> <name>data_store_type</name> <value>complex</value> </Parameter> </parameters> </DataStore> </sourceDataStores> <targetTypes> <FeatureType> <schemaUri>stations.xsd</schemaUri> </FeatureType> </targetTypes> <typeMappings> <FeatureTypeMapping> <sourceDataStore>data_source</sourceDataStore> <sourceType>{collectionName}</sourceType> <targetElement>st:StationFeature</targetElement> <attributeMappings> <AttributeMapping> <targetAttribute>st:StationFeature</targetAttribute> <idExpression> <OCQL>jsonSelect('id')</OCQL> </idExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:name</targetAttribute> <sourceExpression> <OCQL>jsonSelect('name')</OCQL> </sourceExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:contact/st:mail</targetAttribute> <sourceExpression> <OCQL>jsonSelect('contact.mail')</OCQL> </sourceExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:measurement</targetAttribute> <sourceExpression> <OCQL>collectionLink('measurements')</OCQL> <linkElement>aaa</linkElement> <linkField>FEATURE_LINK[1]</linkField> </sourceExpression> <isMultiple>true</isMultiple> </AttributeMapping> <AttributeMapping> <targetAttribute>st:geometry</targetAttribute> <sourceExpression> <OCQL>jsonSelect('geometry')</OCQL> </sourceExpression> </AttributeMapping> </attributeMappings> </FeatureTypeMapping> <FeatureTypeMapping> <sourceDataStore>data_source</sourceDataStore> <sourceType>{collectionName}</sourceType> <mappingName>aaa</mappingName> <targetElement>st:Measurement</targetElement> <attributeMappings> <AttributeMapping> <targetAttribute>st:Measurement</targetAttribute> <idExpression> <OCQL>collectionId()</OCQL> </idExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:name</targetAttribute> <sourceExpression> <OCQL>jsonSelect('name')</OCQL> </sourceExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:unit</targetAttribute> <sourceExpression> <OCQL>jsonSelect('unit')</OCQL> </sourceExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:values</targetAttribute> <sourceExpression> <OCQL>collectionLink('values')</OCQL> <linkElement>st:Value</linkElement> <linkField>FEATURE_LINK[2]</linkField> </sourceExpression> <isMultiple>true</isMultiple> </AttributeMapping> <AttributeMapping> <targetAttribute>FEATURE_LINK[1]</targetAttribute> <sourceExpression> <OCQL>nestedCollectionLink()</OCQL> </sourceExpression> </AttributeMapping> </attributeMappings> </FeatureTypeMapping> <FeatureTypeMapping> <sourceDataStore>data_source</sourceDataStore> <sourceType>{collectionName}</sourceType> <targetElement>st:Value</targetElement> <attributeMappings> <AttributeMapping> <targetAttribute>st:Value</targetAttribute> <idExpression> <OCQL>collectionId()</OCQL> </idExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:timestamp</targetAttribute> <sourceExpression> <OCQL>jsonSelect('time')</OCQL> </sourceExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>st:value</targetAttribute> <sourceExpression> <OCQL>jsonSelect('value')</OCQL> </sourceExpression> </AttributeMapping> <AttributeMapping> <targetAttribute>FEATURE_LINK[2]</targetAttribute> <sourceExpression> <OCQL>nestedCollectionLink()</OCQL> </sourceExpression> </AttributeMapping> </attributeMappings> </FeatureTypeMapping> </typeMappings> </as:AppSchemaDataAccess>
属性的映射很简单,例如以下映射:
<AttributeMapping> <targetAttribute> st:contact / st:mail </ targetAttribute> <sourceExpression> <OCQL> jsonSelect('contact.mail')</ OCQL> </ sourceExpression> </ AttributeMapping>
上面的映射定义了站点的联系人邮件将在JSON路径上可用,contact.mail
并且对应的XML架构元素是XPATH st:contact/st:mail
。
功能链更复杂一点。让我们以链接StationFeature
和Measurement
功能为例。在StationFeature
要素类型中,使用以下映射定义到Measurement实体的链接:
<AttributeMapping> <targetAttribute> st:measurement </ targetAttribute> <sourceExpression> <OCQL> collectionLink('measurements')</ OCQL> <linkElement> st:Measurement </ linkElement> <linkField> FEATURE_LINK [1] </ linkField> </ sourceExpression> <isMultiple> true </ isMultiple> </ AttributeMapping>
在Measurement
要素类型中,使用以下映射定义父要素的链接:
<AttributeMapping> <targetAttribute> FEATURE_LINK [1] </ targetAttribute> <sourceExpression> <OCQL> nestedCollectionLink()</ OCQL> </ sourceExpression> </ AttributeMapping>
通过上面的两个映射,我们将两个要素类型绑定在一起。使用MongoDB数据存储时,此映射将始终小得多,只需要更新嵌套的收集路径和功能链接索引。请注意,嵌套集合属性的JSON路径是相对于父级的。
查询
要在GeoServer中创建MongoDB应用程序架构层,需要安装app-schema扩展和mongo-complex扩展。
需要创建在映射文件中声明的每个名称空间的工作空间,在这种情况下,需要创建st
具有URI 的工作空间http://www.stations.org/1.0
。无需创建gml
工作区。
创建MongoDB应用程序模式层与任何其他应用程序模式层类似,只需创建指向正确映射文件的应用程序模式存储,并选择与顶层实体对应的层,在本例中st:StationFeature
。
可以使用复杂的功能过滤功能查询使用GML和GeoJson编码的WFS复杂功能。例如,查询具有时间戳的测量值的所有站优于1482146964
:
<wfs:Query typeName = “st:StationFeature” > <ogc:Filter> <ogc:Filter> <ogc:PropertyIsGreaterThan> <ogc:PropertyName> st:StationFeature / st:measurement / st:values / st:timestamp </ ogc :PropertyName> <ogc:Literal> 1482146964 </ ogc:Literal> </ ogc:PropertyIsGreaterThan> </ ogc:Filter> </ ogc:Filter> </ wfs:Query>