Coder Social home page Coder Social logo

neo4j-bolt-php's Introduction

THIS REPOSITORY IS ARCHIVED.

Please head to http://github.com/neo4j-php or http://neo4j.com/developer/php for up-to-date PHP support for Neo4j.


Neo4j Bolt PHP

PHP low level Driver for Neo4j's Bolt Remoting Protocol

Build Status


References :

Requirements:

  • PHP5.6+
  • Neo4j3.0
  • PHP Sockets extension available
  • bcmath extension
  • mbstring extension

Installation

Require the package in your dependencies :

composer require graphaware/neo4j-bolt

Setting up a driver and creating a session

use GraphAware\Bolt\GraphDatabase;

$driver = GraphDatabase::driver("bolt://localhost");
$session = $driver->session();

Sending a Cypher statement

$session = $driver->session();
$session->run("CREATE (n)");
$session->close();

// with parameters :

$session->run("CREATE (n) SET n += {props}", ['name' => 'Mike', 'age' => 27]);

Empty Arrays

Due to lack of Collections types in php, there is no way to distinguish when an empty array should be treated as equivalent Java List or Map types.

Therefore you can use a wrapper around arrays for type safety :

use GraphAware\Common\Collections;

        $query = 'MERGE (n:User {id: {id} }) 
        WITH n
        UNWIND {friends} AS friend
        MERGE (f:User {id: friend.name})
        MERGE (f)-[:KNOWS]->(n)';

        $params = ['id' => 'me', 'friends' => Collections::asList([])];
        $this->getSession()->run($query, $params);
        
// Or

        $query = 'MERGE (n:User {id: {id} }) 
        WITH n
        UNWIND {friends}.users AS friend
        MERGE (f:User {id: friend.name})
        MERGE (f)-[:KNOWS]->(n)';

        $params = ['id' => 'me', 'friends' => Collections::asMap([])];
        $this->getSession()->run($query, $params);

TLS Encryption

In order to enable TLS support, you need to set the configuration option to REQUIRED, here an example :

$config = \GraphAware\Bolt\Configuration::newInstance()
    ->withCredentials('bolttest', 'L7n7SfTSj0e6U')
    ->withTLSMode(\GraphAware\Bolt\Configuration::TLSMODE_REQUIRED);

$driver = \GraphAware\Bolt\GraphDatabase::driver('bolt://hobomjfhocgbkeenl.dbs.graphenedb.com:24786', $config);
$session = $driver->session();

License

Copyright (c) 2015-2016 GraphAware Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


neo4j-bolt-php's People

Contributors

ikwattro avatar jerairrest avatar nyholm avatar xavismeh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neo4j-bolt-php's Issues

SerializationException when running client stacks

I'm having a really hard time narrowing down why I am getting serialization errors when running cypher queries on specific node labels through a neo4j-php-client stack over bolt.

When I run:

$st = array( "publish", "draft" );
$stack = $client->stack();
$stack->push("MATCH (n:LOCATION) WHERE (n.status IN {statuses}) RETURN count(*) AS total", [ 'statuses' => $st ], 'total_count');
$stack->push("MATCH (n:LOCATION) WHERE (n.status IN {statuses}) RETURN n ORDER BY n.title ASC SKIP 0 LIMIT 25", [ 'statuses' => $st ], 'paginated_records');
$results = $client->runStack($stack);

I get this exception:

PHP Fatal error:  Uncaught exception 'GraphAware\Bolt\Exception\SerializationException' with message 'Unable to find serialization type for marker d8' in graphaware/neo4j-bolt/src/PackStream/Unpacker.php:204
Stack trace:
#0 graphaware/neo4j-bolt/src/PackStream/Unpacker.php(85): GraphAware\Bolt\PackStream\Unpacker->unpackElement(Object(GraphAware\Bolt\PackStream\BytesWalker))
#1 graphaware/neo4j-bolt/src/PackStream/Unpacker.php(261): GraphAware\Bolt\PackStream\Unpacker->unpackElement(Object(GraphAware\Bolt\PackStream\BytesWalker))
#2 graphaware/neo4j-bolt/src/PackS in graphaware/neo4j-bolt/src/PackStream/Unpacker.php on line 204

But when i run this on a different node label:

$st = array( "publish", "draft" );
$stack = $client->stack();
$stack->push("MATCH (n:REPORT) WHERE (n.status IN {statuses}) RETURN count(*) AS total", [ 'statuses' => $st ], 'total_count');
$stack->push("MATCH (n:REPORT) WHERE (n.status IN {statuses}) RETURN n ORDER BY n.title ASC SKIP 0 LIMIT 25", [ 'statuses' => $st ], 'paginated_records');
$results = $client->runStack($stack);

The query works as expected.

Does this mean something is up with the data in one of my LOCATION nodes somehow? If so, what would cause serialization errors within my nodes? Everything works fine when i connect using the default http protocol, this only applies to bolt connections.

Here are the properties of the LOCATION node that the query chokes on:

leader = (empty)
user_email = [email protected]
located_ivo = (empty)
address = (empty)
source_text = (empty)
image_url = (empty)
country_team = (empty)
mgrs = (empty)
description = (empty)
created_timestamp = 1464901048
title = Test Location
location_type = (empty)
capitol = (empty)
government = (empty)
user_login = matt
information_gaps = (empty)
id = loc_57509db8e09f2
text = (empty)
image_id = (empty)
created_utc = 2016-06-02 08:57:28
slug = test-location
status = publish

And here are the properties of the REPORT node that works just fine:

published_utc = 2016-06-02 08:07:42
user_email = [email protected]
user_login = matt
created_timestamp = 1464898068
id = rep_57509214536b9
text = (empty)
created_utc = 2016-06-02 08:07:48
title = A Report
published_timestamp = 1464854862
slug = a-report
status = publish

Any and all advice is welcome.

Update bolt protocol version (and manage object types)

The driver seems to handle bolt protocol v1 only. I try to update/return object types as parameters (ex : Point) and the server returns this message "Point is not supported as a return type in Bolt protocol version 1. Please make sure driver supports at least protocol version 2. Driver upgrade is most likely required."

As I do not see any new commit for 2 years, I wonder if the driver is still maintained, but I absolutely need to find a solution to manage those types because some of my queries are based on distance calculations and I have a index on a point property. Also, I would like to keep the benefits of parameters and avoid harcoding the point directly in the query.

Does anyone know if I can use any workaround of if an update is sheduled for the driver ?

Accidental var_dump()?

I don't think that this has been done deliberately in src/Protocol/V1/Session.php lines 181 - 184:

if ($shouldThrow !== false) {
    var_dump("cooollll");
    throw $shouldThrow;
}

Error 'Could not pack the value'


Could not pack the value {"message":"A2 19105 Walstraat Rilland rit 20843\n\n29-05-2018 14:58:09 via monitor Jelte\n\n2029570 (Onbekend)\n1320105 Ambulance Zeeland (Connexxion Ambulancezorg) (Ambu 19-105 Goes)\n1320001 Ambulance Zeeland (Regionaal) (Lichtkrant CPA)","message_id":"1452573","posted":1527598708000} {"exception":"[object] (GraphAware\\Bolt\\Exception\\BoltInvalidArgumentException(code: 0): Could not pack the value {\"message\":\"A2 19105 Walstraat Rilland rit 20843\ \ 29-05-2018 14:58:09 via monitor Jelte\ \ 2029570 (Onbekend)\ 1320105 Ambulance Zeeland (Connexxion Ambulancezorg) (Ambu 19-105 Goes)\ 1320001 Ambulance Zeeland (Regionaal) (Lichtkrant CPA)\",\"message_id\":\"1452573\",\"posted\":1527598708000}

Process gets into infinite loop if neo4j goes away

When neo4j becomes unavailable while running a query, the connecting process does not terminate with an exception but stays in an infinite loop, utilizing 100% CPU:

bildschirmfoto von 2017-12-23 01-05-52

Simple steps to reproduce:

  1. Write a script that runs neo4j queries in a loop, add some output after each query is finished.
  2. While it is running, stop neo4j. The script will stop outputting anything and stay at 100% CPU waiting for something.

Starting neo4j again does not change anything, the script will still be in this state.
Got this reproduced on production server and also on my local dev machine.

Memory exhausts when used in a long-running process

I'm trying to export a table from MySQL to Neo4j using a PHP script. The table contains some 2 million rows. The script aborts everytime at around 500k rows with this error:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 62914608 bytes) in E:\code\neo4j-demo\vendor\graphaware\neo4j-bolt\src\PackStream\StreamChannel.php on line 74

Call Stack:
    0.4029     407160   1. {main}() E:\code\neo4j-demo\src\index.php:0
    1.9149    4026888   2. Illuminate\Database\Query\Builder->chunkById() E:\code\neo4j-demo\src\index.php:61
  535.8047   68194584   3. {closure:E:\code\neo4j-demo\src\index.php:46-61}() E:\code\neo4j-demo\vendor\illuminate\database\Concerns\BuildsQueries.php:103
  535.8149   68823696   4. GraphAware\Neo4j\Client\Transaction\Transaction->commit() E:\code\neo4j-demo\src\index.php:56
  535.8156   68860616   5. GraphAware\Bolt\Protocol\V1\Transaction->runMultiple() E:\code\neo4j-demo\vendor\graphaware\neo4j-php-client\src\Transaction\Transaction.php:205
  535.8229   69433616   6. GraphAware\Bolt\Protocol\Pipeline->run() E:\code\neo4j-demo\vendor\graphaware\neo4j-bolt\src\Protocol\V1\Transaction.php:161
  536.5241   69989080   7. GraphAware\Bolt\Protocol\V1\Session->run() E:\code\neo4j-demo\vendor\graphaware\neo4j-bolt\src\Protocol\Pipeline.php:62
  536.5253   69991792   8. GraphAware\Bolt\PackStream\Unpacker->unpack() E:\code\neo4j-demo\vendor\graphaware\neo4j-bolt\src\Protocol\V1\Session.php:106
  536.5254   69991824   9. GraphAware\Bolt\PackStream\StreamChannel->read() E:\code\neo4j-demo\vendor\graphaware\neo4j-bolt\src\PackStream\Unpacker.php:73

The script I'm using is as follows:

<?php

include "../vendor/autoload.php";

use GraphAware\Neo4j\Client\ClientBuilder;
use Illuminate\Container\Container;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Support\Collection;

$config = [
    'driver' => 'mysql',
    'host' => 'localhost',
    'port' => 3306,
    'database' => '...',
    'username' => '...',
    'password' => '...',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_general_ci',
    'prefix' => '',
    'strict' => true,
];

$container = new Container();
$factory = new ConnectionFactory($container);
$mysql = $factory->make($config);

$client = ClientBuilder::create()
    ->addConnection('bolt', 'bolt://neo4j:new4j@localhost:7687')
    ->build();

$total = $mysql->query()->from('follow')->count();

$startTime = time();

$done = 0;
$mysql->query()
    ->from('follow')
    ->chunkById(
        1000,
        function (Collection $rows) use ($total, &$done, $client) {
            echo "$done/$total {$rows->last()->id}\n";

            $tx = $client->transaction();
            foreach ($rows as $row) {
                $tx->push(
                    'MERGE (a:Member {uid:$uid}) MERGE (b:Member {uid:$followUid}) MERGE (a)-[:FOLLOWS]->(b)',
                    ['uid' => $row->uid, 'followUid' => $row->followUid]
                );
            }
            $tx->commit();

            $done += count($rows);
        }
    );

echo time() - $startTime;

Problem with empty arrays used in properties

When serializing the following properties, the query fails:

$properties = [
    'id' => 'whatever',
    'name' => 'some name',
    'tags' => []
 ];

This is due to a problem in GraphAware\Bolt\PackStream\Packer::pack(). If the method encounters a PHP array it uses the following code to determine whether it should serialize the data to a Bolt list or to a Bolt map.

$stream .= ($this->isList($v) && !empty($v)) ? $this->packList($v) : $this->packMap($v);

Because the array is empty the condition falls into the else branch and tries to pack the value as a Bolt map. But maps are not allowed as property values.

Property values can only be of primitive types or arrays thereof	

I'm not 100% sure but I assume, the empty check here is unnecessary, isn't it? Or are there some Bolt restrictions with empty lists?

Connection to GrapheneDB cloud db gives "Error receiving data"

As a test, I've recently created a graphenedb instance in the cloud.

I've filled in the remote connection strings in the config.yml and then I get an "Error receiving data", with no clue what is going wrong.
The scheme, host and port are correct because if I change them, they give a different error. Which is good. The other values (username and pwd), are correct imo. (and with locally configured db, the app works fine.)

Changing the user or password (to incorrect values) results in the same error. (!)

  1. How can I pinpoint what part of the connection config causes the error?

Reading the graphenedb PHP guide, it appears to need a TLS required setting.
2. How do I set this/check if this is set?

Undefined index in /vagrant/vendor/graphaware/neo4j-bolt/src/Record/RecordView.php line 94

Basically, since the if statement here isn't checking whether the array index exists, PHP spits a notice. Not really relevant unless you have something catch or display it, but it would be neat if it didn't generate any errors in the first place.

    public function nodeValue($key)
    {
        if ($this->values[$key] !== null && !$this->values[$key] instanceof NodeInterface) {
            throw new \InvalidArgumentException(sprintf('value for %s is not of type %s', $key, 'NODE'));
        }

        return $this->value($key);
    }

Timeout when submitting a null query

Debian 8, php5-fpm, neo3.0.1

Normally a query text should not be null, but I think it would be better to return a null or something from Session->run($query) if $query==null.

Currently the driver hangs on for long time, generating quite some load on php5-fpm processes

Infinite loop on session

Im having an infinite loop on session recv function that i track to lines 170 and 171 of Session.php file

the queries im running are:

$stack = $this->neo4jClient->stack();
$stack->push("CREATE CONSTRAINT ON (person:Person) ASSERT person.mongoID IS UNIQUE");
$stack->push(
                "CREATE (person:Person) SET person += {info}",
                array('info' => array('mongoID' => (string)$person->getId()))
);
$this->neo4jClient->runStack($stack);

Where the person already exist on database

Strict requirement on PHP >= 5.6

Why is there a strict requirement on PHP >= 5.6? I quickly scanned the code and could not find any trace of any of the PHP 5.6-only features being used,

I know that PHP 5.5 is going to reach end of life shortly, but unfortunately it's still a given fact we have to deal with as our code is still being run on Ubuntu 14.04 for example.

If there isn't a strict dependency on PHP >= 5.6 could this be changed to PHP >= 5.5?

Message: Date is not yet supported as a return type in Bolt

I am getting this error when I try to query my neo4j DB using graphaware/neo4j-bolt-php:

Details
Type: GraphAware\Bolt\Exception\MessageFailureException
Message: Date is not yet supported as a return type in Bolt
File: /------------------/vendor/graphaware/neo4j-bolt/src/Protocol/V1/Response.php
Line: 66
any ideas ??
Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.