MongoDB教程

本教程演示如何将应用程序模式插件与MongoDB数据存储一起使用。本教程将重点介绍MongoDB数据存储的具体特性,强烈建议您在阅读之前阅读应用程序模式文档。

用例

本教程的用例将通过应用程序模式提供有关存储在MongoDB数据库中的一些气象站的信息。注意,这个用例完全是虚构的,只用于演示MongoDB和应用程序模式的集成。

首先,让我们在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"
})

这是将用于在应用程序架构中进行映射的架构:

<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商店

在为MongoDB源配置应用程序架构映射时,可能需要对某些连接参数进行调整,以确保可以识别并使映射可用的完整集。Mongo db存储的设置意味着创建一个Mongo模式,从db集合推断。默认情况下,此进程将使用集合中的随机Mongo对象。如果该对象不包含所有感兴趣的属性,则结果将是一个不完整的架构。因此,可以通过以下两个参数来控制此行为,这两个参数应在 <parameters> 元素下的 <DataStore> 节点:

  • objs_id_schema ,它指定用于构建架构的MongoDB JSON对象的逗号分隔列表(如果 max_objs_schema 存在)。

<Parameter>
  <name>objs_id_schema</name>
  <value>6eb85d889396eb0475f815ef,6eb85d889396eb0475f815eg</value>
</Parameter>
  • max_objs_schema ,它指定用于构建架构的MongoDB JSON对象的最大数量,其中 -1 表示集合中存在的所有对象(如果 objs_id_schema 存在)。

<Parameter>
  <name>max_objs_schema</name>
  <value>-1</value>
</Parameter>

这两个参数也可以通过REST API指定,请参见 Cleaning schemas on internal MongoDB stores 了解更多详细信息。

嵌套元素

MongoDB对象可以包含嵌套元素和嵌套集合。以下三个函数可以使用JSON路径选择嵌套元素并链接嵌套集合:

Function

Example

Description

JSONselect(选择)

jsonselect('contact.mail')

用于从MongoDB对象检索映射的值。

集合链接

collectionlink('测量值')

使用嵌套集合链接实体时使用。

集合ID

集合ID()

指示映射器为嵌套集合生成ID。

嵌套收集链接

嵌套收集链接()

用于嵌套集合,以创建具有父功能的链接。

映射文件示例

站点数据由站点的一些元信息和测量列表组成。每个度量作为一些元信息,包含一个值列表。映射将包含三个顶级实体:站、测量值和值。

遵循完整的映射文件:

<?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>
      <Parameter>
          <name>max_objs_schema</name>
          <value>-1</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 .

特性链接有点复杂。让我们举一个例子 StationFeatureMeasurement 特征。在 StationFeature 要素类型到度量实体的链接通过以下映射定义:

<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层,需要安装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>
Previous: 教程