为不同的数据格式编写自定义分类器 - Amazon 连接词
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

为不同的数据格式编写自定义分类器

您可以提供自定义分类器来对 Amazon Glue中的数据进行分类。您可以使用 grok 模式、XML标签、 JavaScript 对象表示法 (JSON) 或逗号分隔值 () 创建自定义分类器。CSVAmazon Glue 爬网程序调用自定义分类器。如果分类器可识别数据,则它会将数据的分类和架构返回到爬网程序。如果数据与任何内置分类器不匹配,或者您希望自定义由爬网程序创建的表,则可能需要定义自定义分类器。

有关使用 Amazon Glue 控制台创建分类器的更多信息,请参阅使用控制台创建分类器 Amazon Glue

Amazon Glue 按照您指定的顺序在内置分类器之前运行自定义分类器。当爬网程序找到与数据匹配的分类器时,分类字符串和架构将在写入 Amazon Glue Data Catalog的表的定义中使用。

编写 grok 自定义分类器

Grok 是一个工具,用于分析给定匹配模式的文本数据。grok 模式是一组命名的正则表达式 (regex),用于一次匹配一行数据。Amazon Glue 使用 grok 模式来推断数据的架构。当 grok 模式与您的数据匹配时,Amazon Glue 使用该模式来确定数据的结构并将其映射到字段。

Amazon Glue 提供许多内置模式,或者您也可以定义自己的模式。您可以使用自定义分类器定义中的内置模式和自定义模式来创建 grok 模式。您可以定制 grok 模式来对自定义文本文件格式进行分类。

注意

Amazon Glue grok 自定义分类器对在 Amazon Glue Data Catalog中创建的表使用 GrokSerDe 序列化库。如果您在 Amazon Glue Data Catalog 亚马逊 Athena、EMR Amazon 或 Redshift Spectrum 上使用,请查看有关这些服务的文档,了解有关支持的信息。GrokSerDe目前,在查询使用GrokSerDe来自亚马逊EMR和 Redshift Spectrum 的创建的表时,您可能会遇到问题。

以下是 grok 模式组件的基本语法:

%{PATTERN:field-name}

与命名 PATTERN 匹配的数据映射到架构中的 field-name 列,默认数据类型为 string。或者,该字段的数据类型可以在生成的架构中强制转换为 bytebooleandoubleshortintlongfloat

%{PATTERN:field-name:data-type}

例如,要将 num 字段强制转换为 int 数据类型,您可以使用此模式:

%{NUMBER:num:int}

模式可以是由其他模式组成。例如,您可以为 SYSLOG 时间戳指定一个模式,该模式由月份、月份中的日期和时间的模式定义(例如,Feb 1 06:25:43)。对于此数据,您可能定义以下模式:

SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
注意

Grok 模式一次只能处理一行。不支持多行模式。此外,不支持模式中的换行符。

grok 分类器的自定义值

定义 grok 分类器时,需要提供以下值来创建自定义分类器。

名称

分类器的名称。

分类

写入的文本字符串,用于描述分类数据的格式;例如,special-logs

Grok 模式

应用于数据存储以确定是否存在匹配的模式集。这些模式来自 Amazon Glue 内置模式和您定义的任何自定义模式。

以下是 grok 模式的示例:

%{TIMESTAMP_ISO8601:timestamp} \[%{MESSAGEPREFIX:message_prefix}\] %{CRAWLERLOGLEVEL:loglevel} : %{GREEDYDATA:message}

当数据与 TIMESTAMP_ISO8601 匹配时,将会创建架构列 timestamp。此行为与示例中的其他命名模式类似。

自定义模式

您定义的可选自定义模式。这些模式由对您的数据进行分类的 grok 模式引用。您可以在应用于您的数据的 grok 模式中引用这些自定义模式。每个自定义组件模式必须位于不同的行上。正则表达式 (regex) 语法用于定义模式。

下面是如何使用自定义模式的示例:

CRAWLERLOGLEVEL (BENCHMARK|ERROR|WARN|INFO|TRACE) MESSAGEPREFIX .*-.*-.*-.*-.*

第一个自定义命名模式 CRAWLERLOGLEVEL 在数据与其中一个枚举字符串匹配时是匹配项。第二个自定义模式 MESSAGEPREFIX 尝试匹配消息前缀字符串。

Amazon Glue 跟踪分类器的创建时间、上次更新时间和版本。

内置图案

Amazon Glue 可提供许多常见模式,您可以用来构建自定义分类器。您将在分类器定义中向 grok pattern 添加命名模式。

以下列表为每个模式包含一行。在每个行中,模式名称遵循其定义。正则表达式 (regex) 语法用于定义模式。

#<noloc>&GLU;</noloc> Built-in patterns USERNAME [a-zA-Z0-9._-]+ USER %{USERNAME:UNWANTED} INT (?:[+-]?(?:[0-9]+)) BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))) NUMBER (?:%{BASE10NUM:UNWANTED}) BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+)) BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b BOOLEAN (?i)(true|false) POSINT \b(?:[1-9][0-9]*)\b NONNEGINT \b(?:[0-9]+)\b WORD \b\w+\b NOTSPACE \S+ SPACE \s* DATA .*? GREEDYDATA .* #QUOTEDSTRING (?:(?<!\\)(?:"(?:\\.|[^\\"])*"|(?:'(?:\\.|[^\\'])*')|(?:`(?:\\.|[^\\`])*`))) QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``)) UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12} # Networking MAC (?:%{CISCOMAC:UNWANTED}|%{WINDOWSMAC:UNWANTED}|%{COMMONMAC:UNWANTED}) CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4}) WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}) COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}) IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)? IPV4 (?<![0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9]) IP (?:%{IPV6:UNWANTED}|%{IPV4:UNWANTED}) HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-_]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-_]{0,62}))*(\.?|\b) HOST %{HOSTNAME:UNWANTED} IPORHOST (?:%{HOSTNAME:UNWANTED}|%{IP:UNWANTED}) HOSTPORT (?:%{IPORHOST}:%{POSINT:PORT}) # paths PATH (?:%{UNIXPATH}|%{WINPATH}) UNIXPATH (?>/(?>[\w_%!$@:.,~-]+|\\.)*)+ #UNIXPATH (?<![\w\/])(?:/[^\/\s?*]*)+ TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+)) WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+ URIPROTO [A-Za-z]+(\+[A-Za-z+]+)? URIHOST %{IPORHOST}(?::%{POSINT:port})? # uripath comes loosely from RFC1738, but mostly from what Firefox # doesn't turn into %XX URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%_\-]*)+ #URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)? URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]* URIPATHPARAM %{URIPATH}(?:%{URIPARAM})? URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})? # Months: January, Feb, 3, 03, 12, December MONTH \b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b MONTHNUM (?:0?[1-9]|1[0-2]) MONTHNUM2 (?:0[1-9]|1[0-2]) MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9]) # Days: Monday, Tue, Thu, etc... DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?) # Years? YEAR (?>\d\d){1,2} # Time: HH:MM:SS #TIME \d{2}:\d{2}(?::\d{2}(?:\.\d+)?)? # TIME %{POSINT<24}:%{POSINT<60}(?::%{POSINT<60}(?:\.%{POSINT})?)? HOUR (?:2[0123]|[01]?[0-9]) MINUTE (?:[0-5][0-9]) # '60' is a leap second in most time standards and thus is valid. SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?) TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9]) # datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it) DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR} DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR} DATESTAMP_US %{DATE_US}[- ]%{TIME} DATESTAMP_EU %{DATE_EU}[- ]%{TIME} ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE})) ISO8601_SECOND (?:%{SECOND}|60) TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}? TZ (?:[PMCE][SD]T|UTC) DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ} DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE} DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR} DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND} CISCOTIMESTAMP %{MONTH} %{MONTHDAY} %{TIME} # Syslog Dates: Month Day HH:MM:SS SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME} PROG (?:[\w._/%-]+) SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])? SYSLOGHOST %{IPORHOST} SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}> HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT} # Shortcuts QS %{QUOTEDSTRING:UNWANTED} # Log formats SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}: MESSAGESLOG %{SYSLOGBASE} %{DATA} COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{Bytes:bytes=%{NUMBER}|-}) COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent} COMMONAPACHELOG_DATATYPED %{IPORHOST:clientip} %{USER:ident;boolean} %{USER:auth} \[%{HTTPDATE:timestamp;date;dd/MMM/yyyy:HH:mm:ss Z}\] "(?:%{WORD:verb;string} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion;float})?|%{DATA:rawrequest})" %{NUMBER:response;int} (?:%{NUMBER:bytes;long}|-) # Log Levels LOGLEVEL ([A|a]lert|ALERT|[T|t]race|TRACE|[D|d]ebug|DEBUG|[N|n]otice|NOTICE|[I|i]nfo|INFO|[W|w]arn?(?:ing)?|WARN?(?:ING)?|[E|e]rr?(?:or)?|ERR?(?:OR)?|[C|c]rit?(?:ical)?|CRIT?(?:ICAL)?|[F|f]atal|FATAL|[S|s]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)

编写XML自定义分类器

XML使用文件中的标签来定义文档的结构。使用XML自定义分类器,您可以指定用于定义行的标签名称。

分类器的自定义分类器XML值

定义XML分类器时,需要向提供以下值Amazon Glue来创建分类器。此分类器的分类字段设置为 xml

名称

分类器的名称。

行标签

定义XML文档中表格行的XML标签名称,不带尖括号< >。该名称必须符合标签XML规则。

注意

包含行数据的元素不能是自结束的空元素。例如, 不Amazon Glue解析此空元素:

<row att1=”xx” att2=”yy” />

可以如下所示编写空元素:

<row att1=”xx” att2=”yy”> </row>

Amazon Glue 跟踪分类器的创建时间、上次更新时间和版本。

例如,假设您有以下XML文件。要创建仅包含作者和标题列的 Amazon Glue 表,请在 Amazon Glue 控制台中创建 Row tag (行标签)AnyCompany 的分类器。然后,添加并运行使用此自定义分类器的爬网程序。

<?xml version="1.0"?> <catalog> <book id="bk101"> <AnyCompany> <author>Rivera, Martha</author> <title>AnyCompany Developer Guide</title> </AnyCompany> </book> <book id="bk102"> <AnyCompany> <author>Stiles, John</author> <title>Style Guide for AnyCompany</title> </AnyCompany> </book> </catalog>

编写JSON自定义分类器

JSON是一种数据交换格式。它使用名称-值对或值的有序列表来定义数据结构。使用JSON自定义分类器,您可以指定用于定义表架构的数据结构的JSON路径。

Amazon Glue 中的自定义分类器值

定义JSON分类器时,需要向提供以下值Amazon Glue来创建分类器。此分类器的分类字段设置为 json

名称

分类器的名称。

JSON路径

指向用于定义表架构的对象的JSON路径。JSON路径可以用点符号或方括号表示法书写。支持以下运算符:

运算符 描述
$ JSON对象的根元素。这将启动所有路径表达式
* 通配符。JSON路径中需要名称或数字的任何地方都可用。
.<name> 点表示的子字段。在JSON对象中指定子字段。
['<name>'] 括号表示的子字段。指定JSON对象中的子字段。只能指定单个子字段。
[<number>] 数组索引。按索引指定数组的值。

Amazon Glue 跟踪分类器的创建时间、上次更新时间和版本。

例 使用JSON分类器从数组中提取记录

假设您的JSON数据是一个记录数组。例如,您的文件的前几行可能如下所示:

[ { "type": "constituency", "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:1", "name": "Alabama's 1st congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:2", "name": "Alabama's 2nd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:3", "name": "Alabama's 3rd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:4", "name": "Alabama's 4th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:5", "name": "Alabama's 5th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:6", "name": "Alabama's 6th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:7", "name": "Alabama's 7th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:1", "name": "Arkansas's 1st congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:2", "name": "Arkansas's 2nd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:3", "name": "Arkansas's 3rd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:4", "name": "Arkansas's 4th congressional district" } ]

使用内置JSON分类器运行爬网程序时,整个文件将用于定义架构。因为你没有指定JSON路径,所以爬虫会将数据视为一个对象,也就是说,只是一个数组。例如,架构可能如下所示:

root |-- record: array

但是,要创建基于JSON数组中每条记录的架构,请创建自定义JSON分类器并将JSON路径指定为$[*]。当您指定此JSON路径时,分类器会询问数组中的所有 12 条记录以确定架构。生成的架构包含每个对象的单独字段,类似于以下示例:

root |-- type: string |-- id: string |-- name: string
例 使用JSON分类器仅检查文件的一部分

假设您的JSON数据遵循从 http://everypolitician.org/s3://awsglue-datasets/examples/us-legislators/all/areas.json提取的示例JSON文件的模式。JSON文件中的示例对象如下所示:

{ "type": "constituency", "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" } { "type": "constituency", "identifiers": [ { "scheme": "dmoz", "identifier": "Regional\/North_America\/United_States\/Alaska\/" }, { "scheme": "freebase", "identifier": "\/m\/0hjy" }, { "scheme": "fips", "identifier": "US02" }, { "scheme": "quora", "identifier": "Alaska-state" }, { "scheme": "britannica", "identifier": "place\/Alaska" }, { "scheme": "wikidata", "identifier": "Q797" } ], "other_names": [ { "lang": "en", "note": "multilingual", "name": "Alaska" }, { "lang": "fr", "note": "multilingual", "name": "Alaska" }, { "lang": "nov", "note": "multilingual", "name": "Alaska" } ], "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" }

使用内置JSON分类器运行爬网程序时,整个文件将用于创建架构。您最后可能会得到一个如下所示的架构:

root |-- type: string |-- id: string |-- name: string |-- identifiers: array | |-- element: struct | | |-- scheme: string | | |-- identifier: string |-- other_names: array | |-- element: struct | | |-- lang: string | | |-- note: string | | |-- name: string

但是,要仅使用 “id” 对象创建架构,请创建自定义JSON分类器并将JSON路径指定为$.id。然后,该架构仅基于“id”字段:

root |-- record: string

用此架构提取的前几行数据如下所示:

{"record": "ocd-division/country:us/state:ak"} {"record": "ocd-division/country:us/state:al/cd:1"} {"record": "ocd-division/country:us/state:al/cd:2"} {"record": "ocd-division/country:us/state:al/cd:3"} {"record": "ocd-division/country:us/state:al/cd:4"} {"record": "ocd-division/country:us/state:al/cd:5"} {"record": "ocd-division/country:us/state:al/cd:6"} {"record": "ocd-division/country:us/state:al/cd:7"} {"record": "ocd-division/country:us/state:ar/cd:1"} {"record": "ocd-division/country:us/state:ar/cd:2"} {"record": "ocd-division/country:us/state:ar/cd:3"} {"record": "ocd-division/country:us/state:ar/cd:4"} {"record": "ocd-division/country:us/state:as"} {"record": "ocd-division/country:us/state:az/cd:1"} {"record": "ocd-division/country:us/state:az/cd:2"} {"record": "ocd-division/country:us/state:az/cd:3"} {"record": "ocd-division/country:us/state:az/cd:4"} {"record": "ocd-division/country:us/state:az/cd:5"} {"record": "ocd-division/country:us/state:az/cd:6"} {"record": "ocd-division/country:us/state:az/cd:7"}

要基于JSON文件中深度嵌套的对象(例如 “identifier,”)创建架构,可以创建自定义JSON分类器并将JSON路径指定为$.identifiers[*].identifier。尽管架构与前面的示例类似,但它基于JSON文件中的不同对象。

此架构看上去与下类似:

root |-- record: string

如果列出表中的前几行数据,则会指示架构基于“identifier”对象中的数据:

{"record": "Regional/North_America/United_States/Alaska/"} {"record": "/m/0hjy"} {"record": "US02"} {"record": "5879092"} {"record": "4001016-8"} {"record": "destination/alaska"} {"record": "1116270"} {"record": "139487266"} {"record": "n79018447"} {"record": "01490999-8dec-4129-8254-eef6e80fadc3"} {"record": "Alaska-state"} {"record": "place/Alaska"} {"record": "Q797"} {"record": "Regional/North_America/United_States/Alabama/"} {"record": "/m/0gyh"} {"record": "US01"} {"record": "4829764"} {"record": "4084839-5"} {"record": "161950"} {"record": "131885589"}

要基于另一个深度嵌套的对象(例如JSON文件中 “name” 数组中的 “other_names” 字段)创建表,可以创建自定义JSON分类器并将JSON路径指定为$.other_names[*].name。尽管架构与前面的示例类似,但它基于JSON文件中的不同对象。此架构看上去与下类似:

root |-- record: string

如果列出表中的前几行数据,则会指示它基于“name”数组中的“other_names”对象中的数据:

{"record": "Alaska"} {"record": "Alaska"} {"record": "Аляска"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "ألاسكا"} {"record": "ܐܠܐܣܟܐ"} {"record": "الاسكا"} {"record": "Alaska"} {"record": "Alyaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Штат Аляска"} {"record": "Аляска"} {"record": "Alaska"} {"record": "আলাস্কা"}

编写CSV自定义分类器

自定义CSV分类器允许您为自定义 csv 分类器字段中的每列指定数据类型。您可以指定每列的数据类型,用逗号分隔。通过指定数据类型,您可以覆盖爬网程序推断出的数据类型,并确保对数据进行适当分类。

可以在分类 SerDe 器CSV中设置要处理的,分类器将应用于数据目录。

创建自定义分类器时,您也可以将该分类器重复用于不同的爬网程序。

  • 对于只有标题(无数据)的 csv 文件,这些文件将被归类为,UNKNOWN因为提供的信息不足。如果您在 CSV “列标题” 选项中指定 “有标题”,并提供了数据类型,我们可以正确地对这些文件进行分类。

您可以使用自定义CSV分类器来推断各种数据类型的CSV架构。您可以为分类器提供的自定义属性包括分隔符、CSV SerDe 选项、标题选项以及是否对数据执行某些验证。

Amazon Glue 中的自定义分类器值

定义CSV分类器时,需要向提供以下值Amazon Glue来创建分类器。此分类器的分类字段设置为 csv

分类器名称

分类器的名称。

CSVSerde

设置要在 SerDe 分类器CSV中处理的,该分类器将应用于数据目录。选项包括 “打开” CSV SerDe、“Lazy Sim SerDe ple” 和 “无”。当您想让爬网程序执行检测时,可以指定“无”值。

列分隔符

一个自定义符号,表示分隔行中每个列条目的内容。提供一个 Unicode 字符。如果您无法键入分隔符,则可以将其复制并粘贴。这适用于可打印字符,包括您的系统不支持的字符(通常显示为 □)。

引用符号

一个自定义符号,表示将内容组合为单个列值的内容。必须与列分隔符不同。提供一个 Unicode 字符。如果您无法键入分隔符,则可以将其复制并粘贴。这适用于可打印字符,包括您的系统不支持的字符(通常显示为 □)。

列标题

表示应如何在CSV文件中检测列标题的行为。如果您的自定义CSV文件有列标题,请输入以逗号分隔的列标题列表。

处理选项:允许具有单列的文件

允许处理仅包含一列的文件。

处理选项:在标识列值之前去除空格

指定是否在标识列值类型之前去除值。

自定义数据类型 - 可选

输入用逗号分隔的自定义数据类型。指定文件中的自定义数据类型。CSV自定义数据类型必须为受支持的数据类型。支持的数据类型有:“BINARY”、“”、“BOOLEAN”、“”、“DATE”、“DECIMAL”、“”、“DOUBLE”、“FLOAT”、“INT”、“”、“LONG”、“SHORT”、“STRING”、“TIMESTAMP”。不受支持的数据类型将显示错误。