合并关系并不总是有效(延迟)

时间:2017-03-15 13:26:53

标签: javascript neo4j cypher graph-theory graph-databases

在我的项目中,我正在尝试在标签SubjectsAttributes之间建立关系。

我按如下方式设置了相应的关系

MATCH (a:Attribute { aid: {params}.aid } ) 
WITH a 
MATCH (s:Subject { sid: {params}.sid } )
WITH a, s
MERGE (s)-[w:WEIGHTED {wid: {params}.wid }]->(a)
SET w = {params}

问题是,在执行此操作后,并非所有关系都已形成。而且,在我的情况下,应该有52个关系,但最初我只能到达39个地方(它变化)。当我再次调用该函数时,所有52个关系都已解决。

enter image description here

为什么会这样?

一些背景信息:

  • 在设置关系之前,我首先创建节点主题和属性。但是,我只在neo4j服务器解决(使用promises)完成此任务后继续创建实际关系。即主题和属性应该已经填入数据库。

  • 我使用GrapheneDB来托管我的neo4j服务器。

  • 我分离任务的原因,首先创建标签然后创建关系是因为我有多个动态参数(id' s)。

但是,在我可以进行查询以创建关系之前可能有一段延迟?

或者还有别的吗?

我该如何解决这个问题?

HELP!

承诺

非常普遍地说,这是我应用承诺的方式,Queries一个带有密码脚本的数组(它们是正确的)和Params带有相应的参数。

查询1:科目

 function querySubjects() {
            var QueriesAll  = []; // array of strings
            var ParamsAll   = []; // array of objects

            for (var i=0; i<sidArray.length; i++) {

                // [subjects]
                var sid         = sidArray[i];
                var sparams     = {};
                sparams['sid']  = sid;

                // merge subjects
                var queryStr = " \
                MERGE (s:Subject { sid: {sparams}.sid } ) \
                SET s = {sparams} \
                ";

                // [+]
                QueriesAll.push(queryStr);
                ParamsAll.push({
                    sparams: sparams
                });

            } // end s++

            // --> loop queries
            loopQueries(QueriesAll, ParamsAll).then(
                function(success){
                    // -->
                    queryAttributes();
                },
                function(error){
                    // ...
                }
            );
   }

查询2:属性

function queryAttributes() {

        var QueriesAll  = []; // array of strings
        var ParamsAll   = []; // array of objects

        // -----------------------------------------------------------------
        // init attributes
        var aidArray    = [];

        for (var i=0; i<sidArray.length; i++) {

            var sid             = sidArray[i];   // array of keys
            var attributes      = subjects[sid]; // object of attributes
            var attributesArray = Object.keys(attributes);

            for (var j=0; j<attributesArray.length; j++) {
                var aid = attributesArray[j];
                aidArray.push(aid);
            } // end a++

        } // end s++

        // filter out duplicates (works fine)
        aidArray        = aidArray.filter(onlyUnique);

        // -----------------------------------------------------------------
        // create queries

        for (var j=0; j<aidArray.length; j++) {

            // [attributes]
            var aparams             = {};
            aparams['aid']          = aidArray[j];

            // merge attribute
            var queryStr = " \
            MERGE (a:Attribute { aid: {aparams}.aid } ) \
            SET a = {aparams} \
            ";

            // [+]
            QueriesAll.push(queryStr);  
            ParamsAll.push({
                aparams: aparams
            });

        } // end a++


        // --> loop queries
        loopQueries(QueriesAll, ParamsAll).then(
            function(success){
                // -->
                queryWeights();
            },
            function(error){
                // ...
            }
        );
 }

查询3:权重(此处发生问题)

 function queryWeights() {

        var QueriesAll  = []; // array of strings
        var ParamsAll   = []; // array of objects

        for (var i=0; i<sidArray.length; i++) {

            // [subjects]
            var sid         = sidArray[i];
            var sparams     = {};
            sparams['sid']  = sid;

            // [attributes]
            var attributes          = subjects[sid];
            var attributesArray     = Object.keys(attributes);

            for (var j=0; j<attributesArray.length; j++) {

                // ...
                var aid                         = attributesArray[j];
                var aweight                     = attributes[aid];

                var aparams                     = {};
                var wparams                     = {};

                // [weights]
                aparams['aid']          = aid;
                wparams['wid']          = sid + '-' + aid;
                wparams['aweight']      = aweight;

                // merge relationship subject-->attribute
                var queryStr = " \
                  MATCH (a:Attribute{ aid: {aparams}.aid } ) \
                  WITH a \
                  MATCH (s:Subject { sid: {sparams}.sid } ) \
                  WITH a, s \
                  MERGE (s)-[w:WEIGHTED {wid: {wparams}.wid }]->(a) \
                  SET w = {wparams} \
                  RETURN a,s \
                  ";


                // [+]
                QueriesAll.push(queryStr);  
                ParamsAll.push({
                    sparams: sparams,
                    aparams: aparams,
                    wparams: wparams
                });


            } // end a++
        } // end s++


        // --> loop queries
        loopQueries(QueriesAll, ParamsAll).then(
            function(success){
                // <--
                console.log('success')
            },
            function(error){
                // ...
            }
        );

    }

,其中

function loopQueries(Queries, Params) {
    var promises = {};
    for (var i=0; i<Queries.length; i++) {

        var queryStr = Queries[i];
        var params   = Params[i];

        var promise = queryNeo(queryStr, params);
        promises[i] = promise;//promise;
    };
    return Q.all(promises);
}

function queryNeo(queryStr, params) {
    var qq = Q.defer();
    db.cypher({
        query: queryStr,
        params: params,
    }, function (error, results) {
        if (error) { 
            qq.reject(error)
        } else {
            qq.resolve(results)
        }
    });
    return qq.promise;
}

延迟测试

我在创建关系之前等了几秒钟进行了测试。事实上,当我加入延迟时,它会立即生效。我不明白为什么我的查询返回它已完成,而事实并非如此。如何解决这个延迟问题,以便我知道它真的完成了?

1 个答案:

答案 0 :(得分:2)

我不知道这是否会解决您的问题,但您的代码不必要地复杂。至少,简化它应该使它更容易理解和调试。

无需创建包含相同Cypher查询字符串的数组,因此无需使用Q.all()。您可以使用UNWIND调整每个Cypher查询,以便单个查询调用将一次处理每个传入的paramsAll项。

我没有测试过代码的以下修改版本,但它至少应该让您了解如何简化代码。

loopQueries