9.7. JSON转换器

JSON转换器处理JSON文件。要使用JSON转换器,请指定 type = "json" 在您的转换器定义中。

9.7.1. 配置

JSON转换器支持从单个文件中解析多个JSON文档。为了支持JSON路径表达式,每个JSON文档都被完全解析到内存中。对于大型文档,这可能需要相当长的时间和内存。因此,在可能的情况下,每个文件拥有多个较小的JSON文档通常更好。

由于单个JSON文档可能包含多个功能,因此JSON解析器支持 JSONPath 指向每个功能元素的表达式。这可以使用 feature-path 元素。

这个 fields element in a JSON converter supports two additional attributes, path and json-type. path should be a JSONPath 表达式,它相对于 feature-path ,如果已定义(如上所述)。对于绝对路径, root-path 可以用来代替 pathjson-type 应指定正在读取的JSON字段的类型。有效值包括: stringfloatdoubleintegerlongbooleangeometryarrayobject 。该值将被适当地键入,并在 transform 元素为 $0 。几何图形类型可以处理WKT字符串或GeoJSON几何图形对象。

9.7.2. 处理复杂元素

JSON可以包含复杂的嵌套元素,这些元素不一定很好地映射到 SimpleFeatureTypes 。这些类型的元素可以使用GeoMesa的支持轻松处理 JSON属性 。在您的 SimpleFeatureType 架构,通过用户数据提示指示复杂的JSON字符串 json=true 。在您的转换器中,选择外部元素,然后通过 toString 变压器功能。您将能够在查询时使用JSONPath过滤和转换数据。看见 JSON属性 了解更多详细信息。

9.7.3. JSON复合转换器

复合转换器可以在单个流中处理不同的JSON格式。若要使用复合转换器,请指定 type = "composite-json" 在您的转换器定义中。

复合转换器可以定义顶级选项、字段等,与普通JSON转换器相同。这些值将由每个子转换器继承。如果每个子级都是唯一的,则不在顶层定义任何内容都是有效的。

复合转换器必须定义 converters 元素,它是嵌套的JSON转换器定义的数组。除了标准配置之外,每个嵌套的转换器还必须具有 predicate 元素,该元素确定为每个JSON文档使用哪个转换器。传递给谓词的值将是解析后的JSON文档(可用 $0 ),所以通常该谓词将利用 jsonPath 函数(下图)。看见 谓词 以获取有关谓词的更多详细信息。

9.7.4. JSON变换函数

这个 transform 元素支持通过引用JSON元素 $0 。每一列最初将根据该字段的 json-type 。大多数类型将被转换为等价的Java类,例如,java.lang.Integer等。 arrayobject 类型将是原始的JSON元素,因此通常需要进一步处理(例如 jsonListjsonMap ,下文)。

除了中的标准函数之外 变换函数概述 ,JSON转换器提供以下特定于JSON的函数:

9.7.4.1. EmptyJsonToNull

此函数将空的JSON对象和数组转换为NULL。如果JSON对象的所有值都为空,则该对象也被视为空。

9.7.4.2. JsonArrayToObject

此函数使用每个数组元素的索引作为对象键,将JSON数组转换为JSON对象。这对于GeoMesa的JSON属性类型非常有用,它当前需要顶级对象而不是数组。

9.7.4.3. JsonList

此函数用于将JSON数组元素转换为java.util.List。它需要两个参数;第一个是字符串形式的列表元素类型,第二个是JSON数组。列表元素的类型必须是中定义的类型之一 GeoTools要素类型 。请参见下面的示例。

9.7.4.4. JsonMap

此函数用于将JSON对象元素转换为java.util.Map。它需要三个参数;第一个参数是映射关键元素的字符串类型,第二个参数是映射值元素的字符串类型,第三个参数是JSON对象。键和值的类型必须是中定义的类型之一 GeoTools要素类型 。请参见下面的示例。

9.7.4.5. JsonPath

此函数将计算一个 JSONPath 针对给定JSON元素的表达式。一般情况下,最好使用 path 元素中的 fields 元素,但此方法对于复合谓词很有用(请参见上文)。第一个参数是要计算的路径,第二个参数是要操作的元素。

9.7.4.6. MapToJson

此函数用于将java.util.Map转换为JSON字符串。它需要一个单独的参数,该参数必须是一个java.util.Map。它对于将复杂的JSON存储为单个属性非常有用,然后可以使用GeoMesa的JSON属性支持来查询该属性。看见 JSON属性 以获取更多信息。

9.7.4.7. 新JsonObject

此函数用于从键-值对创建新的JSON对象。它对于生成JSON文本值非常有用。

示例::

fields = [
  { name = "foo", path = "$.foo", json-type = "String" }
  { name = "bar", path = "$.bar", json-type = "Array" }
  { name = "foobar", transform = "toString(newJsonObject('foo', $foo, 'bar', $bar))"
]

9.7.5. 用法示例

假定以下SimpleFeatureType:

geomesa.sfts.example = {
  attributes = [
    { name = "name",    type = "String"          }
    { name = "age",     type = "Integer"         }
    { name = "weight",  type = "Double"          }
    { name = "hobbies", type = "List[String]"    }
    { name = "skills",  type = "Map[String,Int]" }
    { name = "source",  type = "String"          }
    { name = "geom",    type = "Point"           }
  ]
}

和以下JSON文档:

{
  "DataSource": { "name": "myjson" },
  "Features": [
    {
      "id": 1,
      "name": "phil",
      "physicals": {
        "age": 32,
        "weight": 150.2
      },
      "hobbies": [ "baseball", "soccer" ],
      "languages": {
        "java": 100,
        "scala": 70
      },
      "geometry": { "type": "Point", "coordinates": [55, 56] }
    },
    {
      "id": 2,
      "name": "fred",
      "physicals": {
        "age": 33,
        "weight": 150.1
      },
      "hobbies": [ "archery", "tennis" ],
      "languages": {
        "c++": 10,
        "fortran": 50
      },
      "geometry": { "type": "Point", "coordinates": [45, 46] }
    }
  ]
}

您可以使用以下转换器进行摄取:

geomesa.converters.myjson = {
  type         = "json"
  id-field     = "$id"
  feature-path = "$.Features[*]"
  fields = [
    { name = "id",      json-type = "integer",  path = "$.id",               transform = "toString($0)"                }
    { name = "name",    json-type = "string",   path = "$.name",             transform = "trim($0)"                    }
    { name = "age",     json-type = "integer",  path = "$.physicals.age",                                              }
    { name = "weight",  json-type = "double",   path = "$.physicals.weight"                                            }
    { name = "hobbies", json-type = "array",    path = "$.hobbies",          transform = "jsonList('string', $0)"      }
    { name = "skills",  json-type = "map",      path = "$.languages",        transform = "jsonMap('string','int', $0)" }
    { name = "geom",    json-type = "geometry", path = "$.geometry",         transform = "point($0)"                   }
    { name = "source",  json-type = "string",   root-path = "$.DataSource.name"                                        }
  ]
}