从Neo4j解析复杂的JSON结果

4
首先,感谢您阅读此文。 其次,抱歉文章有点长 - 但我希望像一个写得好的函数一样,好的东西在前面 - 但请花时间仔细阅读全部内容。 第三,我已经失去了我看过多少个堆栈问题的记录 - 如果这仍然是一个新手问题,我很抱歉。
我正在使用Node.js为我的AngularJS客户端提供api。 我所有的数据聚合和转换都将在Node中完成,并向客户端呈现一个平坦的JSON数据结构。
我有一个Neo4j模型,它将我与我负责的应用程序相关联,并将技术风险与所有应用程序相关联。 我有一个漂亮的Cypher查询,仅显示我负责的应用程序的技术风险,并排除所有没有风险的其他应用程序。 这是我的查询结果的图片: Neo4j Graph result
这是我的node.js代码(由主api.js文件调用的文件routes.js):
var router = require('express').Router();
var neo4j = require('neo4j');
var db = new neo4j.GraphDatabase('http://user:password@localhost:7474');

router.get('/techrisks', getTechRisks);

module.exports = router;

function getTechRisks(req, res) {

    db.cypher({
        query: 'MATCH p=(a)-[e:ARCHITECT_FOR]->(b)-[d:HAS_RISK]->(c) WHERE a.shortname="macdonb" RETURN nodes(p) AS n,relationships(p) AS m',
         params: {

        }
    }, function (err, results) {

        if (err) { throw err; }
        var result = results[0];
        if (!result) {
            console.log('No TechRisk found.');
        } else {
            console.log(results);
            console.log(results[0]);
            console.log(results[1]);
        }
    });
}

上面的代码会生成以下JSON(为了可读性,已添加分隔符)产生以下结果:
- - - - console.log(results); - - - -

[ { n: [ [Object], [Object], [Object] ],
    m: [ [Object], [Object] ] },
  { n: [ [Object], [Object], [Object] ],
    m: [ [Object], [Object] ] },
  { n: [ [Object], [Object], [Object] ],
    m: [ [Object], [Object] ] },
  { n: [ [Object], [Object], [Object] ],
    m: [ [Object], [Object] ] },
  { n: [ [Object], [Object], [Object] ],
    m: [ [Object], [Object] ] } ]

- - - - console.log(results[0]); - - - -

{ n:
   [ Node { _id: 585, labels: [Object], properties: [Object] },
     Node { _id: 675, labels: [Object], properties: [Object] },
     Node { _id: 695, labels: [Object], properties: [Object] } ],
  m:
   [ Relationship {
       _id: 845,
       type: 'ARCHITECT_FOR',
       properties: [Object],
       _fromId: 585,
       _toId: 675 },
     Relationship {
       _id: 813,
       type: 'HAS_RISK',
       properties: [Object],
       _fromId: 675,
       _toId: 695 } ] }

- - - - console.log(results[1]); - - - -

{ n:
   [ Node { _id: 585, labels: [Object], properties: [Object] },
     Node { _id: 674, labels: [Object], properties: [Object] },
     Node { _id: 689, labels: [Object], properties: [Object] } ],
  m:
   [ Relationship {
       _id: 844,
       type: 'ARCHITECT_FOR',
       properties: [Object],
       _fromId: 585,
       _toId: 674 },
     Relationship {
       _id: 810,
       type: 'HAS_RISK',
       properties: [Object],
       _fromId: 674,
       _toId: 689 } ] }

n: 数组让我感到困惑。我开始手动拆分它(尝试使用字符串和对象进行分割和插入),但我相信必须使用json解析器才能访问它。当我使用以下内容作为测试时:
var tmpResult1 = JSON.stringify(result.n);

我得到了一个很棒的n字符串表示:

[{"_id":585,"labels":["Person"],"properties":{"hrpno":"00061627","lastName":"MacDonald","title":"Consultant, IT Architecture","hrdno":"104134","shortname":"macdonb","role":"Systems Architect","displayName":"Bruce MacDonald","firstName":"Bruce"}},{"_id":650,"labels":["Application"],"properties":{"dateverified":"2016-01-19","name":"Portal - Loss Runs","aprmid":"aprm1249"}},{"_id":683,"labels":["TechRisk"],"properties":{"status":"Documented","riskid":"ABC-2012-082","dateEntered":"2012-06-29"}}]

这个字符串很好,但是当我试图使用点号或方括号引用数组时,会出现许多“未定义”错误。

我有点迷失了,准备再休息一两天。我在 YouTube 上寻找教程——“大约有49,300个结果”(!),我已经看了30多个,它们都涉及简单的结构,并以“电影”为例子。

再次感谢您的耐心阅读!我非常感激任何帮助或提示。

3个回答

4
我为此编写了一份专门的库:https://www.npmjs.com/package/parse-neo4j。它解析Neo4j的输出,并仅提取查询中返回的内容,希望能对您有所帮助!Neo4j的http端点生成的结果包含完整的查询信息。parse-neo4j可帮助那些只想要查询返回的常规JSON数据的人。

1
我认为你对 console.log() 的输出感到困惑,它只是一个简短的表示,它并不总是显示对象的全部内容(例如 [Object] 表示存在内部复杂对象)。results 是一个对象而不是 JSON 字符串,执行 console.log(typeof results); 将输出 object
你可以使用 console.log(JSON.stringify(results, null, 3)); 来显示整个对象,这将帮助你通过准确查看属性所在的位置来遍历对象(仅用于调试)。接下来,你不需要解析或分割任何东西,因为 result 是一个有效的 JS 对象,对其进行字符串化只会使事情变得更加困难。例如,尝试 console.log(results[0].n[0].properties.lastName);,它应该显示 MacDonald

我尝试了一下,但出现了以下错误: console.log(result[0].n[0].properties.lastName); ^TypeError: Cannot read property 'n' of undefined at D:\Development\ps_jwt\api\routes.js:205:34 at D:\Development\ps_jwt\api\node_modules\neo4j\lib-new\GraphDatabase.js:301:18我包含了一个答案,说明了我最终是如何处理数组和对象的堆栈的,尽管它仍然不是最好的解决方案。谢谢! - Bruce MacDonald
@BruceMacDonald 我忘记在result中加s了。我已经编辑了我的回答。 - Shanoor
添加“s”后可以正常工作。我同意我想出的答案很复杂。我需要结果返回的3个节点和2个关系的几乎所有属性。感谢您简化这个过程! - Bruce MacDonald

0
经过一晚上的好眠,我想再试一次。我逐步遍历了对象数组等等的数组,并得出了以下结果——这是我的新else条件...
编辑:我忘记提到我最终使用了lodash库。
} else {
    var TechRisk = [];
    for ( var i = 0, len = results.length; i < len; ++i) {
        TechRisk.push(_.defaults(_.get((_.get(results[i], 'n')[0]), 'properties'),_.get((_.get(results[i], 'n')[1]), 'properties'),_.get((_.get(results[i], 'n')[2]), 'properties'),_.get((_.get(results[i], 'm')[0]), 'properties'),_.get((_.get(results[i], 'm')[1]), 'properties')));
    }
    res.status(200).send(TechRisk);
}

如果有人对我嵌套的对象组有更优雅的处理方法,请让我知道。这有点蛮力,而且非常脆弱(我的Cypher查询需要利用参数,以便我可以传入不同的用户等)。

就我目前开发周期而言,这使我向前迈进了一步。

干杯!


这是一个非常简单的问题,但你使用了一个复杂的方式。results 是一个对象,请直接使用它。另外,你具体要查找哪些属性? - Shanoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接