2017-03-15 27 views
0

在我的项目中,我试图创建标签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服务器解决(使用promise)之后,我只着手创建实际的关系。即主题和属性应该已经填充到数据库中。

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

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

但也许有一个延迟之前,我可以使查询创建关系?

或者还有别的吗?

我该如何解决这个问题?

帮助!


承诺

非常generaly说,我这是怎么应用的承诺,为Queries与CYPHER脚本(它们是正确的),并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; 
} 

延迟测试

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

+0

您确定承诺在交易完成时会返回吗?不只是声明,确保完成TX。最好的是如果你分享你的代码。 –

+0

@MichaelHunger我已经分享了脚本。 – JohnAndrews

+0

显示调用'loopQueries'的代码以及创建关系的代码。也就是说,显示整个逻辑流程。 – cybersam

回答

2

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

没有必要创建包含相同的Cypher查询字符串数组,因此没有必要使用Q.all()。您可以使用UNWIND来调整各自的Cypher查询,使一个单一的查询调用会处理所有传入的paramsAll项,一次一个。

我没有测试过你的代码的下面修改后的版本,但它至少应该给你的是如何把事情简单化的想法。 loopQueries函数不再需要。

function querySubjects() { 
    var query = " \ 
     UNWIND {sparams} AS param 
     MERGE (s:Subject { sid: param.sid }) \ 
     SET s = param \ 
     "; 

    var paramsAll = []; // array of objects 

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

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

     paramsAll.push({ 
      sparams: sparams 
     }); 

    } // end s++ 

    // --> loop queries 
    queryNeo(query, paramsAll).then(
     function(success){ 
      // --> 
      queryAttributes(); 
     }, 
     function(error){ 
      // ... 
     } 
); 
} 


function queryAttributes() { 
    var query = " \ 
     UNWIND {aparams} AS param 
     MERGE (a:Attribute { aid: param.aid }) \ 
     SET a = param \ 
     "; 

    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]; 

     paramsAll.push({ 
      aparams: aparams 
     }); 

    } // end a++ 


    // --> loop queries 
    queryNeo(query, paramsAll).then(
     function(success){ 
      // --> 
      queryWeights(); 
     }, 
     function(error){ 
      // ... 
     } 
); 
} 

function queryWeights() { 

    var query = " \ 
     UNWIND {params} AS param 
     MATCH (a:Attribute{ aid: param.aid }) \ 
     MATCH (s:Subject { sid: param.sid }) \ 
     MERGE (s)-[w:WEIGHTED {wid: param.wparams.wid }]->(a) \ 
     SET w = param.wparams \ 
     RETURN a,s \ 
     "; 

    var paramsAll = []; // array of objects 

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

     // [subjects] 
     var sid   = sidArray[i]; 

     // [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 wparams      = {}; 

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

      paramsAll.push({ 
       sid: sid 
       aid: aid, 
       wparams: wparams 
      }); 

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


    // --> loop queries 
    queryNeo(query, paramsAll).then(
     function(success){ 
      // <-- 
      console.log('success') 
     }, 
     function(error){ 
      // ... 
     } 
); 

} 
+0

哇,UNWIND几乎是我在找的东西。我会再试一次,看看它是否有效(我的感觉是,因为我们将这件事全部扣除到3个查询) – JohnAndrews

+0

它工作!确保使用'param'而不是'{param}',并且用它挣扎了一下。 – JohnAndrews