使用 Lumen 和 Neo Eloquent OGM 从 Neo4j 中检索日期时间

Retrive DateTime from Neo4j using Lumen and NeoEloquent OGM

上下文

我正在创建一个 api 休息,它连接到一个已经由节点和边缘填充的图形数据库,该节点和边缘描述事件和展览在几个博物馆内的位置,这些博物馆由区域表征。特别是展览和区域之间有一些边缘,具有开始时间和坐标等属性。 开始时间是一个符合DateTime neo4j格式的属性,下面是一个例子:

{
  "start": "2018-01-01T00:00:01.300Z",
  "coordinate": [
    0,
    0,
    0
  ]
}

我创建边缘的方式是:

CREATE (exhibit)-[:belongs_to {start:datetime('2018-01-01T00:00:01.300Z')}]->(zone)

其中 exhibit 和 zone 分别是节点 ID。

问题

我想从特定边检索开始 [​​=37=],但这是结果:

Unsupported property type: class java.time.ZonedDateTime

代码

findZone 函数产生问题:

<?php

    namespace App;

    use Vinelab\NeoEloquent\Eloquent\Model;
    use App\Http\Controllers\ZoneController;

    class Exhibit extends Model{
        protected $label = 'Exhibit';

        protected $fillable = [];

        protected $hidden = [];

        public function zones(){
            return $this->belongsToMany('App\Zone', 'belongs_to');
        }

        public static function findZone($exhibit){
            $edge = $exhibit->zones()->edge(ZoneController::showZoneByName("Parlatorio"));

            return $edge->start;
        }
    }

我尝试只给边缘坐标 属性 并且当我用坐标替换开始 属性 时函数工作。

堆栈跟踪

Headers: Array
(
    [Date] =>  Mon, 15 Oct 2018 21:28:14 GMT
    [Access-Control-Allow-Origin] =>  *
    [Content-Type] =>  application/json; charset=UTF-8; stream=true
    [Content-Length] =>  6379
)
Body: Array
(
    [message] => Unsupported property type: class java.time.ZonedDateTime
    [exception] => IllegalArgumentException
    [fullname] => java.lang.IllegalArgumentException
    [stackTrace] => Array
        (
            [0] => org.neo4j.server.helpers.PropertyTypeDispatcher.dispatchOtherProperty(PropertyTypeDispatcher.java:246)
            [1] => org.neo4j.server.helpers.PropertyTypeDispatcher.dispatch(PropertyTypeDispatcher.java:95)
            [2] => org.neo4j.server.helpers.PropertyTypeDispatcher.consumeProperties(PropertyTypeDispatcher.java:51)
            [3] => org.neo4j.server.rest.repr.PropertiesRepresentation.serialize(PropertiesRepresentation.java:51)
            [4] => org.neo4j.server.rest.repr.RelationshipRepresentation.extraData(RelationshipRepresentation.java:127)
            [5] => org.neo4j.server.rest.repr.ObjectRepresentation.serialize(ObjectRepresentation.java:147)
            [6] => org.neo4j.server.rest.repr.MappingRepresentation.serialize(MappingRepresentation.java:41)
            [7] => org.neo4j.server.rest.repr.OutputFormat.lambda$stream[=14=](OutputFormat.java:183)
            [8] => org.neo4j.server.rest.dbms.AuthorizationEnabledFilter.doFilter(AuthorizationEnabledFilter.java:123)
            [9] => org.neo4j.server.rest.web.CorsFilter.doFilter(CorsFilter.java:115)
            [10] => org.neo4j.server.rest.web.CollectUserAgentFilter.doFilter(CollectUserAgentFilter.java:69)
            [11] => java.base/java.lang.Thread.run(Unknown Source)
        )

    [errors] => Array
        (
            [0] => Array
                (
                    [code] => Neo.DatabaseError.General.UnknownError
                    [message] => Unsupported property type: class java.time.ZonedDateTime
                    [stackTrace] => java.lang.IllegalArgumentException: Unsupported property type: class java.time.ZonedDateTime
\tat org.neo4j.server.helpers.PropertyTypeDispatcher.dispatchOtherProperty(PropertyTypeDispatcher.java:246)
\tat org.neo4j.server.helpers.PropertyTypeDispatcher.dispatch(PropertyTypeDispatcher.java:95)
\tat org.neo4j.server.helpers.PropertyTypeDispatcher.consumeProperties(PropertyTypeDispatcher.java:51)
\tat org.neo4j.server.rest.repr.PropertiesRepresentation.serialize(PropertiesRepresentation.java:51)
\tat org.neo4j.server.rest.repr.RelationshipRepresentation.extraData(RelationshipRepresentation.java:127)
\tat org.neo4j.server.rest.repr.ObjectRepresentation.serialize(ObjectRepresentation.java:147)
\tat org.neo4j.server.rest.repr.MappingRepresentation.serialize(MappingRepresentation.java:41)
\tat org.neo4j.server.rest.repr.OutputFormat.lambda$stream[=14=](OutputFormat.java:183)
\tat com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:71)
\tat com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:57)
\tat com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:302)
\tat com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
\tat com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
\tat com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
\tat com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
\tat com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
\tat com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:865)
\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1655)
\tat org.neo4j.server.rest.dbms.AuthorizationEnabledFilter.doFilter(AuthorizationEnabledFilter.java:123)
\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
\tat org.neo4j.server.rest.web.CorsFilter.doFilter(CorsFilter.java:115)
\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
\tat org.neo4j.server.rest.web.CollectUserAgentFilter.doFilter(CollectUserAgentFilter.java:69)
\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1317)
\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1219)
\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
\tat org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:61)
\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
\tat org.eclipse.jetty.server.Server.handle(Server.java:531)
\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
\tat org.eclipse.jetty.io.ChannelEndPoint.run(ChannelEndPoint.java:118)
\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
\tat org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
\tat org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:680)
\tat java.base/java.lang.Thread.run(Unknown Source)

                )

        )

)
at E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Command.php:116)
[stacktrace]
#0 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Command\GetRelationship.php(78): Everyman\Neo4j\Command->throwException('Unable to retri...', 500, Array, Array)
#1 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Command.php(69): Everyman\Neo4j\Command\GetRelationship->handleResult(500, Array, Array)
#2 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Client.php(828): Everyman\Neo4j\Command->execute()
#3 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Client.php(544): Everyman\Neo4j\Client->runCommand(Object(Everyman\Neo4j\Command\GetRelationship))
#4 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Relationship.php(102): Everyman\Neo4j\Client->loadRelationship(Object(Everyman\Neo4j\Relationship))
#5 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\PropertyContainer.php(235): Everyman\Neo4j\Relationship->load()
#6 E:\laravel-projects\api_certose\vendor\heydavid713\
eo4jphp\lib\Everyman\Neo4j\Relationship.php(78): Everyman\Neo4j\PropertyContainer->loadProperties()
#7 E:\laravel-projects\api_certose\vendor\vinelab\
eoeloquent\src\Eloquent\Edges\Finder.php(144): Everyman\Neo4j\Relationship->getStartNode()
#8 E:\laravel-projects\api_certose\vendor\vinelab\
eoeloquent\src\Eloquent\Edges\Finder.php(171): Vinelab\NeoEloquent\Eloquent\Edges\Finder->directionFromRelation(Object(Everyman\Neo4j\Relationship), Object(App\Exhibit), Object(App\Zone))
#9 E:\laravel-projects\api_certose\vendor\vinelab\
eoeloquent\src\Eloquent\Edges\Finder.php(80): Vinelab\NeoEloquent\Eloquent\Edges\Finder->edgeFromRelationWithDirection(Object(Everyman\Neo4j\Relationship), Object(App\Exhibit), Object(App\Zone), 'any')
#10 E:\laravel-projects\api_certose\vendor\vinelab\
eoeloquent\src\Eloquent\Relations\BelongsToMany.php(158): Vinelab\NeoEloquent\Eloquent\Edges\Finder->first(Object(App\Exhibit), Object(App\Zone), 'belongs_to')
#11 E:\laravel-projects\api_certose\app\Exhibit.php(20): Vinelab\NeoEloquent\Eloquent\Relations\BelongsToMany->edge(Object(App\Zone))
#12 E:\laravel-projects\api_certose\app\Http\Controllers\ExhibitController.php(44): App\Exhibit::findZone(Object(App\Exhibit))
#13 [internal function]: App\Http\Controllers\ExhibitController->retrieveZone('187')
#14 E:\laravel-projects\api_certose\vendor\illuminate\container\BoundMethod.php(29): call_user_func_array(Array, Array)
#15 E:\laravel-projects\api_certose\vendor\illuminate\container\BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#16 E:\laravel-projects\api_certose\vendor\illuminate\container\BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Laravel\Lumen\Application), Array, Object(Closure))
#17 E:\laravel-projects\api_certose\vendor\illuminate\container\Container.php(564): Illuminate\Container\BoundMethod::call(Object(Laravel\Lumen\Application), Array, Array, NULL)
#18 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(373): Illuminate\Container\Container->call(Array, Array)
#19 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(339): Laravel\Lumen\Application->callControllerCallable(Array, Array)
#20 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(313): Laravel\Lumen\Application->callLumenController(Object(App\Http\Controllers\ExhibitController), 'retrieveZone', Array)
#21 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(275): Laravel\Lumen\Application->callControllerAction(Array)
#22 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(260): Laravel\Lumen\Application->callActionOnArrayBasedRoute(Array)
#23 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(230): Laravel\Lumen\Application->handleFoundRoute(Array)
#24 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(164): Laravel\Lumen\Application->handleDispatcherResponse(Array)
#25 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(413): Laravel\Lumen\Application->Laravel\Lumen\Concerns\{closure}()
#26 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(166): Laravel\Lumen\Application->sendThroughPipeline(Array, Object(Closure))
#27 E:\laravel-projects\api_certose\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php(107): Laravel\Lumen\Application->dispatch(NULL)
#28 E:\laravel-projects\api_certose\public\index.php(28): Laravel\Lumen\Application->run()
#29 {main}
"} 

我也遇到了这个问题,但未能找到您想要的解决方法。据我所知,它在 neoeloquent 库本身中。但是我想出了一个不理想的替代方案,因为能够使用库来完成它会更好但它有效。

我写了一个 RawQueryService,它可以采用原始 Neo4j 查询并将输出检索为关联数组。

RawQueryService如下:

<?php

namespace App\Services;

use Illuminate\Support\Facades\DB;

class RawQueryService
{

    public static function executeRawQuery(string $query, $noProcessing=false) {
        $result = DB::select($query);

        $resultArray = array();
        foreach($result as $row){
            $result = $row['n'];
            array_push($resultArray, $result);
        }

        return $resultArray;
    }


}

然后检索开始时间:

$start = \App\Services\RawQueryService::executeRawQuery(
         "match(n) where n.title=\"".$title."\" return toString(n.start)");

它在内部将日期时间转换为字符串,因此 Neo4j 库不会收到 IllegalArgumentException

希望对您有所帮助。

我一直在解决这个问题,发现在服务器 REST API 中序列化 datetime 属性存在问题。根据 http 与 bolt 和查询类型的不同,会生成一些不同的错误,但是当 datetime 属性从响应中删除时,它们就会消失。

服务器的

v3.5.0 已针对 HTTP 请求修复它。我还没有验证这个版本的螺栓。

我的调查和解决方案的更多详细信息位于 https://github.com/neo4jrb/neo4j/issues/1522(ruby gem 客户端)。 v3.4.1 和 3.4.6 都存在这个问题。