bagatela-graph - połączona struktura do wyszukiwania i analizy połączeń
API (Interfejs Programowania Aplikacji) umożliwia programowy dostęp do danych (węzłów, połączeń, przesiadek) i usług (wyszukiwarka encji, wyszukiwarka połączeń) z poziomu aplikacji trzecich.
API jest zgodne ze wzorcem REST. Interakcja na zbiorach odbywa się protokołem HTTP i pozwala na wykonywanie zapytań typu GET i POST. Dane przyjmowane i zwracane są w formacie JSON.
Dla każdego dnia instnieje osobny graf:
http://graph.bagate.la/<YYYY-MM-DD>
Zawiera on w sobie dane ze wszystkich miast (obsługiwanych tego dnia).
UWAGA: Graph API jest w fazie beta i przez pewien okres API dostępne będzie jedynie przez adres:
http://graph.bagate.la/demo
Wszystkie przykłady interakcji z API korzystają z prostego narzędzia konsoli
curl i zostały wykonane w systemie GNU/Linux.
$ curl http://graph.bagate.la --verbose
* About to connect() to graph.bagate.la port 80 (#0)
* Trying 31.222.178.135... connected
> GET / HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-unknown-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.0e zlib/1.2.5 libssh2/1.3.0
> Host: graph.bagate.la
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.0.9
< Date: Thu, 17 Nov 2011 18:27:44 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Access-Control-Allow-Origin: *
<
* Connection #0 to host graph.bagate.la left intact
* Closing connection #0
{"version":"0.7-SNAPSHOT","name":"Rexster: A Graph Server","graphs":["demo"],"queryTime":0.138796,"upTime":"0[d]:00[h]:03[m]:40[s]"}
(również do dokumentacji) jest mile widziana! Weź https://github.com/Stanley/bagatela na widły i poproś o akceptacje zmian.
Interfejs programistyczny jest oparty o serwer Rexster, który udostępnia dane przechowywane w bazie danych OrientDB. Jego szczegóły opisano w dokumentacji Rexster REST API.
Graf składa się wyłącznie z wierzchołków i skierowanych relacji między nimi, zwanych krawędziami. Dalszy podział tych zasobów na klasy jest umowny, gdyż ich atrybuty nie są ograniczone żadną strukturą. OrientDB organizuje dane w tzw. klastrach, które są przypisane do każdej klasy.
Graf jest strukturą połączoną, co znaczy że dane które on zawiera, są od siebie zależne. Naturalną konsekwencją tego jest API, które zwraca te zależności w postaci linków, czyli adresów URI, zawsze tam gdzie ma to sens. Zaleca się w ten sposób "odkrywać" graf, zamiast polegać na dokumentacji, gdyż uchroni nas to przez możliwymi zmianami API w przyszłości. Odkrywanie najlepiej zacząć od korzenia:
Ścieżka: /
Metoda: GET
Odpowiedź: 200 - referencje do najważniejszych zasobów. 404 - graf nie
istnieje (brak danych z danego dnia lub zły format daty).
Przykładowe użycie:
$ curl http://graph.bagate.la/demo/
{"version":"0.7-SNAPSHOT","name":"demo","graph":"readonlyindexablegraph[orientgraph[local:\/home\/orientdb\/demo]]","readOnly":true,"type":"com.tinkerpop.blueprints.pgm.impls.orientdb.OrientGraph","queryTime":2.618832,"upTime":"0[d]:00[h]:04[m]:51[s]","extensions":[{"title":"evaluate an ad-hoc Gremlin script for a graph.","method":"GET","href":"tp\/gremlin"},{"title":"evaluate an ad-hoc Gremlin script for a graph.","method":"POST","href":"tp\/gremlin"}]}
W dowolnej chwili dostępne są grafy dla dnia bieżącego oraz siedmiu następnych. Dane historyczne są archiwizowane i dostępne jedynie w następujący sposób:
Ścieżka: .gz
Metoda: GET
Odpowiedź: 200 - zarchiwizowana baza danych. 404 - graf nie
istnieje (brak danych z danego dnia lub zły format daty).
Przykładowe użycie:
$ cd <ścieżka do orientdb>
$ wget http://graph.bagate.la/2011-08-18.gz
$ ./bin/console.sh
OrientDB console v.1.0rc6 (build @BUILD@) www.orientechnologies.com
Type 'help' to display all the commands supported.'
> create database local:/tmp/bagatela admin admin local
Creating database [local:/tmp/bagatela] using the storage type [local]...
Database created successfully.
Current database is: local:/tmp/bagatela
> import database 2011-08-18.gz
Importing database from file 2011-08-18.gz...
Dane mogą zostać wykorzystane np. do stworzenia lokalnej instancji bazy danych OrientDB, wizualizacji grafu, analizy itp.
Wierzchołek w grafie. Reprezentuje punkt na mapie. Węzły są tworzone na podstawie przystanków.
Ścieżka: /vertices/<id>
Metoda: GET
Parametry: id - identyfikator węzła.
Odpowiedź: 200 - wartości atrybutów i referencje do relacji węzła. 404 -
węzeł nie istnieje.
Przykładowe użycie:
$ curl http://graph.bagate.la/demo/vertices/7:77
{"version":"0.7-SNAPSHOT","results":{"lon":19.93278833333333,"name":"Teatr Bagatela","lat":50.06352999999999,"_id":"#7:77","_type":"vertex"},"queryTime":1.458626}
_id - unikalny identyfikator w formie: "#<cluser>:<position>". Np. "#8:16"_type - zawsze "vertex".lat - szerokość geograficzna. Np.: 50.123.lon - długość geograficzna. Np.: 19.987.source - adres URI do dokumentu, na podstawie którego został utworzony ten
węzeł (istnieje tylko dla klasy "Stop"). Np.:
"http://api.bagate.la/kr/abc?rev=def".W sytuacji, gdy nie mamy wiedzy o tym który dokładnie przystanek każdy rozkład
jazdy reprezentuje (brak wartości stop_id w dokumencie
Timetable), zbiór przystanków o tej samej nazwie,
będzie reprezentowany na grafie tylko przez jeden węzeł klasy Hub. Sprawi to,
że nie pojawią się relacje przesiadek, dlatego przy trawersacji nie będziemy w
stanie stwierdzić czy nastąpiło przejście z jednego przystanku do drugiego o
tej samej nazwie. Klasa Stop reprezentuje fizyczny przystanek (wiata albo
słupek).
Relacja między dwoma węzłami. Zachodzi gdy istnieje przynajmniej jedna linia, która kursuje między nimi bezpośrednio (np. linia jeżdżąca po przystankach A → B → C, składa się z dokładnie dwóch połączeń: A do B i B do C).
Ścieżka: /vertices/<id>/<dir>E?_label=connects
Metoda: GET
Parametry: id - identyfikator węzła, dir - kierunek relacji. Może być in, out lub both.
Odpowiedź: 200 - połączenia (przychodzące, wychodzące lub wszystkie) z węzła id.
Przykładowe użycie:
$ curl http://graph.bagate.la/2011-11-10/vertices/31/outE?_label=connects
_id - unikalny identyfikator w formie: "#cluser:position". Np. "#9:10"_inV - indentyfikator węzła wejściowego._label - zawsze "connects"._outE - indentyfikator węzła wyjściowego._type - zawsze "edge".rides - lista kursów wszystkich linii na danej krawędzi. Atrybut typu
tablicy asocjacyjnej. Przechowuje pary, w których godzinie odjazdu (w formacie
liczby minut od północy; np. dla "12:00" jest to "720") odpowiada tablica z
informacjami o połączeniu (patrz niżej).length - długość odcinka w metrach. Liczona wzdłuż trasy (jeżeli ta jest
zdefiniowana w polu polylines przystanku
początkowego), lub po linii prostej.Obiekt typu tablicy asocjacyjnej, zawierającej następujące pary:
line - numer linii. Np. "4".duration - czas podróży w minutach. Np. 2.Relacja między dwoma węzłami klasy Stop. Jeżeli istnieje relacja z węzła A do B to istnieje też druga, inna relacja z węzła B do A.
Ścieżka: /vertices/<id>/<dir>E?_label=transfers
Metoda: GET
Parametry: id - identyfikator węzła, dir - kierunek relacji. Może być in, out lub both.
Odpowiedź: 200 - przesiadki (do, z lub wszystkie) z węzła <id>.
_id - unikalny identyfikator w formie: "#cluser:position". Np. "#10:1"_inV - indentyfikator węzła wejściowego._label - zawsze "transfers"._outE - indentyfikator węzła wyjściowego._type - zawsze "edge".penatly - orientacyjny czas w minutach, potrzeby do przemieszczenia się z
jednego węzła do drugiego. Np.: 1.Usługa, która pozwala na wyszukiwanie węzłów i relacji według dowolnych kryteriów. Zwrócony element często jest jedynie zalążkiem do wyszukiwania ścieżek i innych struktur powstających w procesie trawersacji grafu. Ponieważ silnikiem wyszukiwarki jest elasticsearch, pełna dokumentacja API znajduje się na stronie: http://www.elasticsearch.org/guide/reference/api/search/.
Ścieżka: /search?q=<fraza>
Metoda: GET
Paramerty:
q - fraza. Akceptuje mi. wieloznaczniki * i ? oraz wyrażenia logiczne OR i AND.sort (opcjonalnie) - sortowanie, np.: "name:asc" (po nazwie, rosnąco). Domyślnie po trafności.size (opcjonalnie) - maksymalna liczba dokumentów spełniających kryteria zapytania.Odpowiedź: lista węzłów spełniających kryteria tj. zawierają frazę w nazwie lub lokalizacji.
Frazę można doprecyzować, dopisując przed nią name: lub address:, co ograniczy wyszukiwanie do określonego pola.
Alternatywne użycie:
Ścieżka: /search
Metoda: POST
Ładunek: Zapytanie DSL w formacie JSON
DSL (język zapytania) jest udokumentowany na stronie: http://www.elasticsearch.org/guide/reference/query-dsl/. Ta forma pozwala formułować bardziej skomplikowane zapytania, ale wymaga znajomości języka.
Przechodzenie grafu w zdefiniowany sposób. Zaczynamy zawsze od jednego wierzchołka (lub krawędzi), a następnie, po jego krawędziach (lub jej wierzchołkach), odwiedzamy kolejne encje (wiele w tym samym czasie). Celem tego procesu może być uzyskanie np.: węzłów, krawędzi lub obu tych typów, odwiedzonych w procesie trawersacji.
Do definicji sposobu przechodzenia grafu służy Gremlin, będący rozszerzeniem języka Groovy. Pozwala on na wykonywanie szeregu operacji ad-hoc na grafie.
Ścieżka: /tp/gremlin
Metoda: POST
Parametry:
rexster.showTypes - displays the properties of the elements with their native data type (default is false),rexster.returnKeys - the element property keys to return (default is to return all element properties),rexster.offset.start - start index for a paged set of data to be returned,rexster.offset.end - end index for a paged set of data to be returnedscript - the Gremlin script to be evaluatedOdpowiedź: 200 - węzły, krawędzie, ścieżka (identyfikatory węzłów i krawędzi)
lub pełna ścieżka wraz z atrybutami węzłów i krawędzi. 404 - węzeł id nie
istnieje.
Połączenie komunikacyjne jest ścieżką, która składa się z węzłów, połączonych konkretnym odjazdem (lub przesiadką). W przeciwieństwie do zwykłej trawersacji, nie jest to lista wszystkich kursów (odjazdów) w danym połączeniu. Ponieważ wynik jest związany z czasem, zarówno kursy jak i węzły mogą zależeć od czasu, będącym jednym z parametrów tego zapytania.
Ścieżka: już wkrótce
Metoda: POST
Parametry: id - identyfikator węzła początkowego.
Parametry ładunku:
start_at - czas odjazdu z węzła początkowego (nie wcześniej niż
start_at).finish_at - czas przejazdu na węzeł docelowy (nie później niż
finish_at). Jeżeli parametr start_at jest zdefiniowany, finish_at
zostanie zignorowany.time_limit - limit czasu trwania połączenia w minutach. Domyślnie 120.to - węzeł docelowy.Odpowiedź: 200 - teoretycznie (zgodnie z algorytmem A*) najszybsze czasowo połączenie komunikacyjne, pomiędzy dwoma wierzchołkami grafu.