【问题标题】:Optimize a Cypher Query with loop for builing a time tree使用循环优化 Cypher 查询以构建时间树
【发布时间】:2015-11-17 17:41:27
【问题描述】:

我想为日历功能创建一个时间树 - 它可以工作,但我意识到它非常慢(每 20 秒插入 1 次)。也许有人暗示如何更改代码以获得更高的性能?

for ($calYear=2012;$calYear<2016; $calYear++)
{
        $paramsYear =array(
        "pYear" => $calYear, 
        "UUID" => uniqid()            
    );


$queryString = '
    MERGE (y:calTime:calYear {name: {pYear}}) 
    SET 
    y.uuid= {UUID},
    y.created="'.time().'",
    y.active="Y"    
    return y;
    ';

    $query = new Everyman\Neo4j\Cypher\Query($client, $queryString,$params);
    $result = $query->getResultSet();    

    for ($calMonth=1;$calMonth<13; $calMonth++)
    {
                $paramsMonth =array(
                "pYear" => $calYear, 
                "pMonth" => $calMonth, 
                "UUID" => uniqid()            
            );            
        $queryString = '
            MATCH (y:calTime:calYear {name: {pYear}})
            MERGE (m:calTime:calMonth {name: {pMonth}) -[:IS_MONTH_OF]->(y) 
            SET 
            m.uuid= {UUID},
            m.created="'.time().'",
            m.active="Y"    
            return m;
            ';

            $query = new Everyman\Neo4j\Cypher\Query($client, $queryString,$paramsMonth);
            $result = $query->getResultSet();    

            $numberOfDays = date("t",mktime(0, 0, 0, $calMonth, 1, $calYear));

            for ($calDay=1;$calDay<=$numberOfDays; $calDay++)
            {
                    $paramsDay =array(
                    "pYear" => $calYear, 
                    "pMonth" => $calMonth, 
                    "pDay" => $calDay, 
                    "UUID" => uniqid()            
                );  

                $queryString = '
                    MATCH (y:calTime:calYear {name: {pYear}) -- (m:calTime:calMonth {name: {pMonth})
                    MERGE (d:calTime:calDay {name: {pDay}) -[:IS_DAY_OF]->(m)
                    SET 
                    d.uuid= {UUID},
                    d.created="'.time().'",
                    d.active="Y" 
                    return d;
                    ';

                    $query = new Everyman\Neo4j\Cypher\Query($client, $queryString,$paramsDay);
                    $result = $query->getResultSet();                   

                    for ($calHour=1;$calHour<=24; $calHour++)
                    {
                    $paramsHour =array(
                    "pYear" => $calYear, 
                    "pMonth" => $calMonth, 
                    "pDay" => $calDay, 
                    "pHour" => $calHour, 
                    "UUID" => uniqid()            
                );  

                        $queryString = '
                            MATCH (y:calTime:calYear {name: {pYear}) -- (m:calTime:calMonth {name: {pMonth}) -- (d:calTime:calDay {name: {pDay}) 
                            MERGE (h:calTime:calHour {name: {pHour}) -[:IS_HOUR_OF]->(d)
                            SET 
                            h.uuid= {UUID},
                            h.created="'.time().'",
                            h.active="Y"  
                            return h;
                            ';

                            $query = new Everyman\Neo4j\Cypher\Query($client, $queryString,$paramsHour);
                            $result = $query->getResultSet();

                    } // End Hour

            } // End Day
    } // End Month                
} // End Year

【问题讨论】:

    标签: php neo4j cypher


    【解决方案1】:

    这并不奇怪,您的代码将为每个 Cypher 语句执行 x 个不同的 http 查询,这并没有使用 http 事务端点的所有好处。因此,对于每个查询,您都会在查询时间中计算 http 延迟。

    1. 创建一个包含所有要执行的查询的数组并一次性执行,我不知道 neo4jphp 将如何执行,但在 NeoClient PHP 中,您可以使用 PreparedTransaction 对象轻松完成

    2. neo4j 插件可以在后台为您处理时间树的创建/更新,https://github.com/graphaware/neo4j-timetree 并且有一个 NeoclientPHP timetree extension 为您提供使用 neo4j 时间树插件 API 所需的方法

    【讨论】:

    • 谢谢,交易提示很有价值!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多