- Оригинальный адрес:Powering PHP With JanusGraph
- Оригинальный автор:Don Omondi
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:GanymedeNil
- Корректор:allenlongbaobao
JanusGraph поддерживает PHP
По мере того, как популярность JanusGraph росла, разработчики, несомненно, создавали вокруг него инструменты. В этом посте от ComposeWrite StuffВ этой статье Дон Омонди, основатель и технический директор Campus Discounts, рассказывает о своей новой библиотеке PHP для JanusGraph и рассказывает, как ее использовать.
В мире языков программирования PHP не нуждается в особом представлении. Он официально выпустил версию 1.0 в 1995 году. PHP теперь стал основой многих компаний-единорогов, в первую очередь Facebook, а в последнее время и Slack. По состоянию на сентябрь 2017 г.W3TechsСогласно отчету, PHP используется на 82,8% всех известных веб-сайтов в качестве серверного языка программирования!
JanusGraph — новичок в мире баз данных, но он имеет глубокие технические корни, поскольку основан на Titan, предыдущем лидере графовых баз данных с открытым исходным кодом. Чтобы дать вам некоторые сведения о базах данных графов, см.Введение в графовые базы данных. Хотя JanusGraph еще молод, его уже использует известная компания-единорог Uber.
Итак, главный вопрос заключается в том, как создать компанию-единорога с помощью PHP и JanusGraph? Поверьте мне, я бы тоже хотел знать ответ! Но что, если вопрос заключается в том, как усилить безопасность PHP с помощью JanusGraph? Я знаю больше, чем один способ.
Введение в PHP-библиотеку Gremlin-OGM
Gremlin-OGMБиблиотека PHP представляет собой средство отображения графов объектов для графовых баз данных, совместимых с Tinkerpop 3+ (JanusGraph, Neo4j и т. д.), позволяющее сохранять данные и выполнять запросы гремлина.
Библиотека уже размещена на Packagist, поэтому его можно легко установить с помощью Composer.
composer require the-don-himself/gremlin-ogm
Пользоваться библиотекой также легко, потому что она имеет большое количество комментариев PHP. Но прежде чем мы начнем, давайте углубимся в некоторые проблемы, с которыми вы можете столкнуться при использовании графовой базы данных, такой как JanusGraph, и как библиотека может помочь вам избежать их.
Меры предосторожности
Во-первых, все свойства с одинаковыми именами должны иметь одинаковый тип данных. Если у вас уже есть данные в другой базе данных, например MySQL или MongoDB, вы можете столкнуться с этой ситуацией.
Хорошим примером является каждый класс сущностей или документ, называемыйid
поле. Некоторые идентификаторы могут иметь целочисленный тип данных (1, 2, 3 и т. д.), другие могут быть строкового типа (например, идентификаторы в библиотеке часто задаваемых вопросов).en_1
,es_1
,fr_1
), в дополнение, например, к UUID MongoDB (пример59be8696540bbb198c0065c4
). Исключение возникает, когда одно и то же имя свойства используется для этих разных типов данных. Библиотека Gremlin-OGM обнаружит такой конфликт и откажется выполнять. В качестве обходного пути я бы предложил объединить теги со словамиid
комбинации; например, идентификатор пользователя становитсяusers_id
. Библиотека поставляется с сериализатором, который позволяет вам сопоставлять поля с виртуальными свойствами, чтобы избежать этого конфликта.
Во-вторых, имена свойств, метки ребер и метки вершин должны быть уникальными в графе. Например, пометив Vertex какtweets
и сослаться на объект, затем создать ребро, отмеченное какtweets
и ссылаться на действие пользователя, или вusers
Создайте свойство в Vertextweets
указать количество твитов, сделанных пользователем. Библиотека также обнаружит этот конфликт и откажется выполняться.
В-третьих, для производительности и достоверности схемы я рекомендую обеспечить, чтобы каждый элемент или, по крайней мере, каждая вершина содержали уникальный атрибут, для которого будет создан уникальный составной индекс (он же ключевой индекс). Это гарантирует, что все элементы уникальны, и повысит производительность, поскольку для добавления ребер между вершинами сначала требуется запросить, существуют ли они. Эта библиотека позволяет использовать для этой цели@Id
Атрибуты тега аннотации.
Наконец, указатель. Этот пункт заслуживает книги или двух. В JanusGraph в основном вы индексируете свойства (в конце концов, это граф свойств), но вы можете использовать одно и то же имя свойства на разных вершинах и ребрах. Будьте очень осторожны при этом. Помните первое, что нужно знать. Так, например, по умолчанию свойствоtotal_comments
Индексы будут охватывать все вершины и ребра. запрос, которыйtotal_comments
больше, чем5
вершины вернутсяtotal_comments > 5
изusers
,total_comments > 5
и смесь любых других вершин, удовлетворяющих этому запросу. Еще хуже, через некоторое время, если выrecipes
вершина плюс одинtotal_comments
свойство, то ваш существующий запрос завершится ошибкой.
Чтобы предотвратить потенциальные проблемы, упомянутые выше, JanusGraph позволяет вам установить параметр метки при создании индекса, чтобы ограничить его область действия. Я рекомендую сделать это, чтобы индексы были меньше и более производительными, но это означает, что вы должны дать каждому индексу уникальное имя. Библиотека Gremlin-OGM ищет любые конфликтующие имена индексов и отказывается выполняться, если они найдены.
Как использовать Гремлин-ОГМ
Чтобы начать работу с Gremlin-OGM, нам сначала нужно создать каталог с именем Graph в нашей исходной папке, например.src/Graph
. В этом каталоге нам нужно создать два разных каталога: один называется Vertices, а другой — Edges. Эти два каталога теперь будут содержать классы PHP, которые определяют наши элементы диаграммы.
Каждый класс в папке вершин в основном использует аннотации для описания меток вершин, связанных индексов и атрибутов. Для более продвинутых вариантов использования, если вы используете MongoDB и имеете класс, содержащий встроенные документы (например, набор аннотаций), вы также можете определить наиболее подходящие ребра для встраивания.
Каждый класс в папке края также описывает метку края, связанный индекс и свойства посредством аннотаций. Два свойства в каждом классе ребер также могут быть помечены аннотациями, одна из которых описывает, откуда связаны вершины, а другая описывает, откуда связаны вершины. Он действительно прост в использовании, но давайте проиллюстрируем это на примере.
Практический пример: Твиттер
Базы данных Twitter и графов действительно подходят друг другу. Такие объекты, как пользователи и твиты, могут образовывать вершины, а такие операции, как подписка, лайки, твиты и ретвиты, могут образовывать ребра. Обратите внимание, что крайtweeted
назван так, чтобы избежатьtweets
конфликт. Графическое представление этой простой модели можно показать на рисунке ниже.
Создадим соответствующие классы в папке Graph/Vertexes и папке Graph/Edges. Класс твитов может выглядеть так:
<?php
namespace TheDonHimself\GremlinOGM\TwitterGraph\Graph\Vertices;
use JMS\Serializer\Annotation as Serializer;
use TheDonHimself\GremlinOGM\Annotation as Graph;
/**
* @Serializer\ExclusionPolicy("all")
* @Graph\Vertex(
* label="tweets",
* indexes={
* @Graph\Index(
* name="byTweetsIdComposite",
* type="Composite",
* unique=true,
* label_constraint=true,
* keys={
* "tweets_id"
* }
* ),
* @Graph\Index(
* name="tweetsMixed",
* type="Mixed",
* label_constraint=true,
* keys={
* "tweets_id" : "DEFAULT",
* "text" : "TEXT",
* "retweet_count" : "DEFAULT",
* "created_at" : "DEFAULT",
* "favorited" : "DEFAULT",
* "retweeted" : "DEFAULT",
* "source" : "STRING"
* }
* )
* }
* )
*/
class Tweets
{
/**
* @Serializer\Type("integer")
* @Serializer\Expose
* @Serializer\Groups({"Default"})
*/
public $id;
/**
* @Serializer\VirtualProperty
* @Serializer\Expose
* @Serializer\Type("integer")
* @Serializer\Groups({"Graph"})
* @Serializer\SerializedName("tweets_id")
* @Graph\Id
* @Graph\PropertyName("tweets_id")
* @Graph\PropertyType("Long")
* @Graph\PropertyCardinality("SINGLE")
*/
public function getVirtualId()
{
return self::getId();
}
/**
* @Serializer\Type("string")
* @Serializer\Expose
* @Serializer\Groups({"Default", "Graph"})
* @Graph\PropertyName("text")
* @Graph\PropertyType("String")
* @Graph\PropertyCardinality("SINGLE")
*/
public $text;
/**
* @Serializer\Type("integer")
* @Serializer\Expose
* @Serializer\Groups({"Default", "Graph"})
* @Graph\PropertyName("retweet_count")
* @Graph\PropertyType("Integer")
* @Graph\PropertyCardinality("SINGLE")
*/
public $retweet_count;
/**
* @Serializer\Type("boolean")
* @Serializer\Expose
* @Serializer\Groups({"Default", "Graph"})
* @Graph\PropertyName("favorited")
* @Graph\PropertyType("Boolean")
* @Graph\PropertyCardinality("SINGLE")
*/
public $favorited;
/**
* @Serializer\Type("boolean")
* @Serializer\Expose
* @Serializer\Groups({"Default", "Graph"})
* @Graph\PropertyName("retweeted")
* @Graph\PropertyType("Boolean")
* @Graph\PropertyCardinality("SINGLE")
*/
public $retweeted;
/**
* @Serializer\Type("DateTime<'', '', 'D M d H:i:s P Y'>")
* @Serializer\Expose
* @Serializer\Groups({"Default", "Graph"})
* @Graph\PropertyName("created_at")
* @Graph\PropertyType("Date")
* @Graph\PropertyCardinality("SINGLE")
*/
public $created_at;
/**
* @Serializer\Type("string")
* @Serializer\Expose
* @Serializer\Groups({"Default", "Graph"})
* @Graph\PropertyName("source")
* @Graph\PropertyType("String")
* @Graph\PropertyCardinality("SINGLE")
*/
public $source;
/**
* @Serializer\Type("TheDonHimself\GremlinOGM\TwitterGraph\Graph\Vertices\Users")
* @Serializer\Expose
* @Serializer\Groups({"Default"})
*/
public $user;
/**
* @Serializer\Type("TheDonHimself\GremlinOGM\TwitterGraph\Graph\Vertices\Tweets")
* @Serializer\Expose
* @Serializer\Groups({"Default"})
*/
public $retweeted_status;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
}
API Twitter очень выразителен, хотя на самом деле мы можем хранить гораздо больше данных, чем позволяют классы вершин. Однако в этом примере нас интересуют только несколько свойств. Приведенные выше аннотации сообщают сериализатору, что эти поля следует заполнять только при десериализации данных Twitter API в объекты класса вершин.
заusers
Vertex создает аналогичный класс. Полный код примера находится в папке TwitterGraph в библиотеке.
Пример можно создать в папке Graph/EdgesFollows
Класс Edge выглядит так:
<?php
namespace TheDonHimself\GremlinOGM\TwitterGraph\Graph\Edges;
use JMS\Serializer\Annotation as Serializer;
use TheDonHimself\GremlinOGM\Annotation as Graph;
/**
* @Serializer\ExclusionPolicy("all")
* @Graph\Edge(
* label="follows",
* multiplicity="MULTI"
* )
*/
class Follows
{
/**
* @Graph\AddEdgeFromVertex(
* targetVertex="users",
* uniquePropertyKey="users_id",
* methodsForKeyValue={"getUserVertex1Id"}
* )
*/
protected $userVertex1Id;
/**
* @Graph\AddEdgeToVertex(
* targetVertex="users",
* uniquePropertyKey="users_id",
* methodsForKeyValue={"getUserVertex2Id"}
* )
*/
protected $userVertex2Id;
public function __construct($user1_vertex_id, $user2_vertex_id)
{
$this->userVertex1Id = $user1_vertex_id;
$this->userVertex2Id = $user2_vertex_id;
}
/**
* Get User 1 Vertex ID.
*
*
* @return int
*/
public function getUserVertex1Id()
{
return $this->userVertex1Id;
}
/**
* Get User 2 Vertex ID.
*
*
* @return int
*/
public function getUserVertex2Id()
{
return $this->userVertex2Id;
}
}
заlikes
,tweeted
иretweets
Edge создает аналогичные классы. После этого мы можем проверить достоверность модели, запустив:
php bin/graph twittergraph:schema:check
Если возникают исключения, то нам нужно сначала их разрешить; в противном случае наша модель настроена, и все, что нам нужно сделать сейчас, это сообщить JanusGraph.
Соединение JanusGraph
TheDonHimself\GremlinOGM\GraphConnection
Класс отвечает за инициализацию графического соединения. Вы можете сделать это, создав новый экземпляр и передав некоторые параметры подключения в массиве.
$options = [
'host' => 127.0.0.1,
'port' => 8182,
'username' => null,
'password' => null,
'ssl' = [
'ssl_verify_peer' => false,
'ssl_verify_peer_name' => false
],
'graph' => 'graph',
'timeout' => 10,
'emptySet' => true,
'retryAttempts' => 3,
'vendor' = [
'name' => _self',
'database' => 'janusgraph',
'version' => '0.2'
],
'twitter' => [
'consumer_key' => 'LnUQzlkWlNT4oNUh7a2rwFtwe',
'consumer_secret' => 'WCIu0YhaOUBPq11lj8psxZYobCjXpYXHxXA6rVcqbuNDYXEoP0',
'access_token' => '622225192-upvfXMpeb9a3FMhuid6oBiCRsiAokpNFgbVeeRxl',
'access_token_secret' => '9M5MnJOns2AFeZbdTeSk3R81ZVjltJCXKtxUav1MgsN7Z'
]
];
Массив поставщиков может указывать информацию, указывающую поставку, такую как Gremll-совместимая база данных, версия, имя хоста (или_self
родной) и название графика.
Чтобы окончательно создать модель, мы запустим эту команду.
php bin/graph twittergraph:schema:create
Эта команда потребует необязательныйconfigPath
параметр, который включается при установлении соединенияoptions
Расположение файла конфигурации yaml для массива. В библиотеке есть три примера конфигураций в корневой папке,janusgraph.yaml
,janusgraphcompose.yaml
иazure-cosmosdb.yaml
.
Приведенная выше команда будет рекурсивно проходить по нашемуTwitterGraph/Graph
каталог и найти все@Graph
аннотации для построения определений модели. При обнаружении будет выдано исключение; в противном случае будет запущена транзакция Graph для одновременной фиксации всех атрибутов, ребер и вершин или отката в случае сбоя.
Эта же команда также спросит вас, хотите ли вы выполнитьdry run
. Если указано, команда не будет отправлена на сервер Gremlin, а будет сброшена во что-то, что вы можете проверить.command.groovy
в файле. Для примера с Twitter эти 26 строк представляют собой команды, отправленные или выгруженные в соответствии с вашей конфигурацией (например, janusgraph _self native).
mgmt = graph.openManagement()
text = mgmt.makePropertyKey('text').dataType(String.class).cardinality(Cardinality.SINGLE).make()
retweet_count = mgmt.makePropertyKey('retweet_count').dataType(Integer.class).cardinality(Cardinality.SINGLE).make()
retweeted = mgmt.makePropertyKey('retweeted').dataType(Boolean.class).cardinality(Cardinality.SINGLE).make()
created_at = mgmt.makePropertyKey('created_at').dataType(Date.class).cardinality(Cardinality.SINGLE).make()
source = mgmt.makePropertyKey('source').dataType(String.class).cardinality(Cardinality.SINGLE).make()
tweets_id = mgmt.makePropertyKey('tweets_id').dataType(Long.class).cardinality(Cardinality.SINGLE).make()
name = mgmt.makePropertyKey('name').dataType(String.class).cardinality(Cardinality.SINGLE).make()
screen_name = mgmt.makePropertyKey('screen_name').dataType(String.class).cardinality(Cardinality.SINGLE).make()
description = mgmt.makePropertyKey('description').dataType(String.class).cardinality(Cardinality.SINGLE).make()
followers_count = mgmt.makePropertyKey('followers_count').dataType(Integer.class).cardinality(Cardinality.SINGLE).make()
verified = mgmt.makePropertyKey('verified').dataType(Boolean.class).cardinality(Cardinality.SINGLE).make()
lang = mgmt.makePropertyKey('lang').dataType(String.class).cardinality(Cardinality.SINGLE).make()
users_id = mgmt.makePropertyKey('users_id').dataType(Long.class).cardinality(Cardinality.SINGLE).make()
tweets = mgmt.makeVertexLabel('tweets').make()
users = mgmt.makeVertexLabel('users').make()
follows = mgmt.makeEdgeLabel('follows').multiplicity(MULTI).make()
likes = mgmt.makeEdgeLabel('likes').multiplicity(MULTI).make()
retweets = mgmt.makeEdgeLabel('retweets').multiplicity(MULTI).make()
tweeted = mgmt.makeEdgeLabel('tweeted').multiplicity(ONE2MANY).make()
mgmt.buildIndex('byTweetsIdComposite', Vertex.class).addKey(tweets_id).unique().indexOnly(tweets).buildCompositeIndex()
mgmt.buildIndex('tweetsMixed',Vertex.class).addKey(tweets_id).addKey(text,Mapping.TEXT.asParameter()).addKey(retweet_count).addKey(created_at).addKey(retweeted).addKey(source,Mapping.STRING.asParameter()).indexOnly(tweets).buildMixedIndex("search")
mgmt.buildIndex('byUsersIdComposite',Vertex.class).addKey(users_id).unique().indexOnly(users).buildCompositeIndex()
mgmt.buildIndex('byScreenNameComposite',Vertex.class).addKey(screen_name).unique().indexOnly(users).buildCompositeIndex()
mgmt.buildIndex('usersMixed',Vertex.class).addKey(users_id).addKey(name,Mapping.TEXTSTRING.asParameter()).addKey(screen_name,Mapping.STRING.asParameter()).addKey(description,Mapping.TEXT.asParameter()).addKey(followers_count).addKey(created_at).addKey(verified).addKey(lang,Mapping.STRING.asParameter()).indexOnly(users).buildMixedIndex("search")
mgmt.commit()
Теперь, когда у нас есть рабочая модель, нам нужны только данные. API Twitter имеет хорошую документацию о том, как запрашивать эти данные. Библиотека Gremlin-OGM поставляется сtwitteroauthСумка (abraham/twitteroauth) и готовое приложение Twitter, доступное только для чтения, для тестирования библиотеки и помощи в начале работы.
После получения данных из API сохранить вершины очень просто. Сначала десериализуйте JSON в соответствующий объект класса вершин. Так, например,@TwitterDev
Через полученные данные Twitter/api/users/show
будет десериализован, как показаноvar_dump()
.
object(TheDonHimself\GremlinOGM\TwitterGraph\Graph\Vertices\Users)#432 (8) {
["id"]=>
int(2244994945)
["name"]=>
string(10) "TwitterDev"
["screen_name"]=>
string(10) "TwitterDev"
["description"]=>
string(136) "Developer and Platform Relations @Twitter. We are developer advocates. We can't answer
all your questions, but we listen to all of them!"
["followers_count"]=>
int(429831)
["created_at"]=>
object(DateTime)#445 (3) {
["date"]=>
string(26) "2013-12-14 04:35:55.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
["verified"]=>
bool(true)
["lang"]=>
string(2) "en"
}
Сериализованные объекты PHP теперь начали формироваться в соответствующих вершинах и ребрах. Однако мы можем отправлять команды гремлина только в виде строк, поэтому нам все равно нужно сериализовать объект как командную строку. Мы будем использовать класс с удобным названиемGraphSerializer
сделать это. Передайте десериализованный объект вGraphSerializer
Экземпляр, который будет обрабатывать сложную сериализацию, такую как удаление новых строк, добавление косых черт, преобразование PHPDateTime
Преобразование в формат, ожидаемый JanusGraph.GraphSerializer
Также изящно обрабатывает сериализацию Geopoint и Geoshape.
// Get Default Serializer
$serializer = SerializerBuilder::create()->build();
// Get Twitter User
$decoded_user = $connection->get(
'users/show',
array(
'screen_name' => $twitter_handle,
'include_entities' => false,
)
);
if (404 == $connection->getLastHttpCode()) {
$output->writeln('Twitter User @'.$twitter_handle.' Does Not Exist');
return;
}
// Use default serializer to convert array from Twitter API to Users Class Object handling complex
deserialization like Date Time
$user = $serializer->fromArray($decoded_user, Users::class);
// Initiate Special Graph Serializer
$graph_serializer = new GraphSerializer();
// Use graph serializer to convert Users Class Object to array handling complex deserialization like
Geoshape
$user_array = $graph_serializer->toArray($user);
// Use graph serializer to convert array to a gremlin command string ready to be sent over
$command = $graph_serializer->toVertex($user_array);
Вывод GraphSerializer будет сериализован в команды Gremlin. Эта строка готова к отправке на сервер JanusGraph. Таким образом, в приведенном выше примере это становится:
"g.addV(label, 'users', 'users_id', 2244994945, 'name', 'TwitterDev', 'screen_name', 'TwitterDev', 'description', 'Developer and Platform Relations @Twitter. We are developer advocates. We can\'t answer all your questions, but we listen to all of them!', 'followers_count', 429831, 'created_at', 1386995755000, 'verified', true, 'lang', 'en')"
Сохранение ребер немного проще, так как предполагает наличие фиксированных точек. Поэтому библиотеке необходимо знать пары ключ-значение свойства, чтобы найти их. Кроме того, ребра имеют ориентацию и кратность в базе данных графа. Поэтому очень важно, чтобы ребра добавлялись к вершинам.
Это в классе Edge@Graph\AddEdgeFromVertex
и@Graph\AddEdgeToVertex
Назначение аннотаций свойств. все они расширяются@Graph\AddEdge
Аннотация для указания целевого класса вершин и массива ключей свойств и методов, необходимых для получения значения.
Предположим, мы запросили твиты в Twitter API, который содержит файл с именемuser
встроенное поле для хранения данных твитера. еслиusers_id:5
созданныйtweets_id:7
, сериализованная команда гремлина будет выглядеть так:
if (g.V().hasLabel('users').has('users_id',5).hasNext() == true
&& g.V().hasLabel('tweets').has('tweets_id',7).hasNext() == true)
{
g.V().hasLabel('users').has('users_id',5).next().addEdge('tweeted',
g.V().hasLabel('tweets').has('tweets_id',7).next())
}
Следовательно, два вершинных запроса — это одна транзакция, и тогда вusers
иtweets
Создайте два ребра между ними. Обратите внимание: поскольку пользователь может твитить несколько раз, но у каждого твита может быть только один владелец, повторяемостьONE2MANY
.
Если класс края имеет что-то вродеtweeted_on
илиtweeted_from
свойства, подобные этому, библиотека сериализует их соответствующим образом, как вершины.
Запрос JanusGraph
Обрабатываем очищенные и сохраненные данные. Запросы данных также выполняются с помощью библиотеки.TheDonHimself\Traversal\TraversalBuilder
Классы предоставляют собственный API, который почти идеально соответствует гремлину. Например, получение пользователей в TwitterGraph можно реализовать следующим образом.
$user_id = 12345;
$traversalBuilder = new TraversalBuilder();
$command = $traversalBuilder
->g()
->V()
->hasLabel("'users'")
->has("'users_id'", "$user_id")
->getTraversal();
Чуть более сложный пример, такой как получение пользовательской временной шкалы, можно реализовать следующим образом.
$command = $traversalBuilder
->g()
->V()
->hasLabel("'users'")
->has("'screen_name'", "'$screen_name'")
->union(
(new TraversalBuilder())->out("'tweeted'")->getTraversal(),
(new TraversalBuilder())->out("'follows'")->out("'tweeted'")->getTraversal()
)
->order()
->by("'created_at'", 'decr')
->limit(10)
->getTraversal();
Подробные шаги можно найти в\TheDonHimself\Traversal\Step
нашел в классе.
GraphQL в Гремлин
существует одиннезависимая попыткадля создания стандарта, поддерживающего команды GraphQL to Gremlin. Он находится на ранней стадии и поддерживает только запросы, а не изменения. Поскольку она тоже была написана мной, библиотека Gremlin-OGM, безусловно, поддерживает этот стандарт, надеюсь, со временем она улучшится.
Визуализация JanusGraph
К сожалению, у него не так много графических интерфейсов базы данных Graph, как у реляционных баз данных, баз данных документов и баз данных типа "ключ-значение". вGephi, который можно использовать для визуализации данных и запросов JanusGraph с помощью потоковых плагинов. В то же время существует браузер данных, написанный с помощью JanusGraph, который можно использовать для отображения некоторых запросов TwitterGraph.
Визуализируйте 5 пользователей, на которых я подписан
def graph = ConfiguredGraphFactory.open("twitter");
def g = graph.traversal();
g.V().hasLabel('users').has('screen_name',
textRegex('(i)the_don_himself')).outE('follows').limit(5).inV().path()
Визуализируйте 5 пользователей, которые подписаны на меня
def graph = ConfiguredGraphFactory.open("twitter");
def g = graph.traversal();
g.V().hasLabel('users').has('screen_name',
textRegex('(i)the_don_himself')).inE('follows').limit(5).outV().path()
Визуализируйте мои 5 любимых твитов
def graph = ConfiguredGraphFactory.open("twitter");
def g = graph.traversal();
g.V().hasLabel('users').has('screen_name',
textRegex('(?i)the_don_himself')).outE('likes').limit(5).inV().path()
Визуализируйте любые 5 ретвитов и оригинальные твиты
def graph = ConfiguredGraphFactory.open("twitter");
def g = graph.traversal();
g.V().hasLabel('tweets').outE('retweets').inV().limit(5).path()
Теперь у вас есть это. Мощная, продуманная и простая в использовании библиотека, которая поможет вам начать работу с JanusGraph на PHP за считанные минуты. Если вы используете удивительный фреймворк Symfony, вам больше повезло. предстоящие пакетыGremlin-OGM-BundleПоможет вам скопировать данные из RDBMS или MongoDB в графовую базу данных, совместимую с Tinkerpop 3+. Пожалуйста, наслаждайтесь!
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллекти другие поля, если вы хотите видеть больше качественных переводов, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.