Definição do Problema
Entidades do Knowledge Graph (também conhecidas como nós) são ligadas por relacionamentos; valores de entidade ESRI__ID são chaves estrangeiras nas colunas de relacionamento ESRI__OriginID e ESRI__DestID. Os valores de ID são derivados do tipo de dado GlobalID, e são gerados pelo sistema. Como os valores ESRI__ID precisam existir nas entidades antes que você possa usá-los em relacionamentos, muitas pessoas pensam que é necessário criar ou manter um grafo em duas etapas, primeiro as entidades e depois separadamente os relacionamentos, e acabam com duas ferramentas ETL para gerenciar, ou mais se o processamento for feito por combinação de entidade e relacionamento. Isto é desnecessário.
Este blog mostra como você pode manter um grafo usando uma única ferramenta ETL que grava tanto entidades quanto relacionamentos em uma única execução.
Cenário do Grafo
Primeiramente, veja o obrigatório - e muito movimentado - mapa! O assunto do grafo de hoje é dados mundiais de aeroportos e voos para 24 horas antes e depois do horário de execução da ferramenta ETL, então cerca de metade dos voos estão no passado e a outra metade está programada para o futuro próximo. Note que as rotas dos voos não modelam as rotas reais das aeronaves, o grafo destina-se apenas a modelar a conectividade. Mais sobre cenários de uso está abaixo.
Aeroportos e voos mundiais
A Ferramenta ETL
Os dados são disponibilizados pela FlightAware a partir dos seus endpoints AeroAPI, acessados por esta ferramenta ETL - disponível no download do blog. Você precisará da sua própria chave API.
Ferramenta ETL de passagem única para manutenção do grafo
Mesmo que você não tenha acesso ao AeroAPI, baixe e descompacte o anexo do blog e instale o conteúdo conforme segue (requer ArcGIS Data Interoperability para Pro 3.5+):
- Create.fmw - coloque este arquivo fonte do workspace na pasta principal do projeto Pro
- Caso queira, crie uma ferramenta ETL usando o fmw como fonte
- LoopingAirportsGetter.fmx - um transformador personalizado usado pelo Create.fmw
- Coloque este na pasta do seu perfil de usuário C:\Users\<seunomeusuario>\Documents\FME\Transformers
Há muito material útil que cobriremos nas ferramentas, mas para ir direto ao objetivo principal do blog - como gravar entidades e relacionamentos em um único workspace - você verá no Create.fmw que primeiro escreve as entidades no grafo com um transformador FeatureWriter, depois usa a porta Summary do FeatureWriter para disparar a leitura das entidades de volta ao workspace com um transformador FeatureReader - eles então têm os valores ESRI__ID necessários. O workspace não está disposto compactamente para mostrar essa sequência mas procure pelo transformador chamado FeatureWriter que grava aeroportos e você verá uma conexão direta da porta Summary dele para o transformador chamado FeatureReader lendo os aeroportos recém gravados. Portas Summary produzem uma única feição não espacial com algumas propriedades identificadoras e estatísticas após a transação de gravação ser confirmada.
A escrita dos relacionamentos pode ser feita com escritores comuns do Esri Knowledge Graph pois eles não têm dependência a jusante. Se isso é tudo que você veio buscar hoje então não precisa ler mais, mas se gosta de mergulhos profundos em ETL provavelmente aprenderá algo no restante da postagem, então continue lendo!
Estou criando um grafo com dados obtidos de uma API, e uma que segue prática moderna padrão - chamadas REST retornam respostas JSON paginadas, e toda a API tem uma especificação OpenAPI. Você pode inspecionar a API neste URL e notar o link para a especificação OpenAPI.
Como a especificação OpenAPI está disponível, ela pode ser importada para um transformador OpenAPICaller, que transforma a construção da chamada HTTP em um exercício de preenchimento de formulário. Aqui está o primeiro OpenAPICaller no workspace. Note que estou solicitando 100 páginas (1500 registros) de dados de aeroportos e o cabeçalho inclui um parâmetro da ferramenta para a chave API e uma solicitação para receber uma resposta JSON. O esquema dos aeroportos não é muito amplo então 1500 registros não sobrecarregam a resposta HTTP GET nem causam erros, mas estou obtendo apenas um conjunto inicial de registros, não todos os dados dos aeroportos.
OpenAPICaller para Aeroportos
A API suporta paginação. Se uma requisição não retorna os últimos registros disponíveis no servidor então um objeto JSON chamado next (uma URL) está disponível na resposta, enviá-la como requisição retorna o próximo conjunto de páginas. Isso se presta a um loop para obter todos os dados, que é o que o transformador personalizado LoopingAirportsGetter faz.
LoopingAirportsGetter
Como a próxima URL é construída para nós podemos usar um HTTPCaller simples no transformador personalizado, não outro OpenAPICaller. Agora temos todos os dados dos aeroportos e podemos gravar o tipo da entidade.
Se você inspecionar a ferramenta, verá que depois das entidades dos aeroportos serem gravadas no grafo elas são lidas novamente (com valores ESRI__ID) e outro OpenAPICaller obtém voos para cada aeroporto. Desta vez são recuperadas 50 páginas de dados por chamada (o esquema é mais amplo) mas podemos ter 25 chamadas simultâneas pois não estamos paginando através de um cursor grande no back-end, mas sim os voos de cada aeroporto.
OpenAPICaller para Voos
Existem alguns aeroportos mundialmente com mais de 50 páginas de voos (750 registros) ao longo de 48 horas e estes são recuperados com um HTTPCaller se next não é nulo a partir de uma solicitação inicial.<\/P>
Observe os parâmetros de consulta start<\/STRONG> e end<\/STRONG>. Estes são timestamps UTC no formato ISO, gerados na hora de início da ferramenta por parâmetros scriptados - então algum código entrou na minha ferramenta ETL! Isso poderia ser feito com transformers.<\/P>O Grafo no ArcGIS<\/H4> <\/P>Vou deixar você explorar a ferramenta para inspecionar a lógica de construção de entidade & relacionamento, mas basicamente os tipos de entidade são Airports<\/STRONG> (pontos) e Flights<\/STRONG> (linhas de 2 pontos) e os relacionamentos são aeroportos têm partidas em voos (HasDeparture<\/STRONG>), voos podem ter conexões com outros voos (HasConnection<\/STRONG>) e voos têm chegadas em aeroportos (HasArrival<\/STRONG>). A lógica de negócio usada para conexões é que voos estão conectados se um voo de chegada pousa entre 1 e 4 horas antes do voo de partida decolar. Na vida real pode haver outros fatores como acordos de code share, mas isso é apenas uma demonstração!<\/P>Aqui está a visão do modelo de dados do grafo, aeroportos e voos têm relacionamentos entre si e voos têm conexões com outros voos. A entidade Document não é usada.<\/P>
FlightAware Graph Data Model<\/span><\/span><\/P>Agora vamos fazer uma consulta analítica! Digamos que eu sou um agente da lei e quero pedir às companhias aéreas e aeroportos para verificar manifestos de passageiros e filmagens recentes para um suspeito ladrão de joias que eu acho que saiu de Los Angeles para viajar para Berlim, ou está prestes a fazer isso. Quais companhias aéreas, voos e aeroportos fazem mais sentido consultar? Claro que eu uso minhas habilidades openCypher<\/A> e uso meu grafo atualizado diariamente!<\/P>Vou deixar você analisar o código, mas o que ele faz é encontrar o caminho de menor tempo de voo entre Los Angeles e Berlin-Brandenberg, com no máximo 4 trechos de voo.<\/P>
match path = (origin:Airports)-[:HasDeparture|:HasConnection*0..3]->(:Flights)-[:HasArrival]->(destination:Airports)\nwhere origin.name = 'Los Angeles Intl' AND destination.name = 'Berlin-Brandenburg'\nwith path, nodes(path) as flights\nunwind flights as flight\nwith path, sum(case when flight:Flights then flight.filed_ete else 0 end) as totalDuration\nreturn path, (totalDuration\/3600) as totalDuration\norder by totalDuration\nlimit 1<\/code><\/pre> Um caminho é retornado da minha consulta....<\/P>
Discussão<\/H4> <\/P>Isto demonstra tanto a abordagem de ferramenta única quanto muito mais sobre o uso de dados API e Knowledge Graphs.<\/STRONG> O espaço ETL no download está em estado pronto para execução assumindo que você tem uma chave API e já construiu o grafo antes - ele está atualizado. A ferramenta pode ser executada usando o recurso regular de agendamento de ferramentas do ArcGIS Pro, digamos diariamente. Você não estará neste estado inicialmente, mas verá alguns transformers Creator que podem ser usados para executar a ferramenta manualmente em partes, por exemplo para criar as entidades Airports. Trabalhe assim desativando temporariamente Creators ou outros transformers que estejam em fluxos que você não deseja. Eu criei relacionamentos vazios manualmente pois Knowledge suporta especificar a origem e destino para relacionamentos (para que possa exibir o modelo de dados).<\/P>Comente neste post se tiver perguntas ou observações. Divirta-se com seu ETL de grafo!<\/P>