如何在Neo4j Cypher中处理JSON时解决困境?

时间:2013-12-30 14:32:10

标签: javascript json node.js neo4j

我发现在编写Node.js应用程序时,我无法在Cypher查询中使用标准JSON字符串:

var neo4j = require('neo4j')
   ,db = new neo4j.GraphDatabase('http://localhost:7474')
   ,enc_datum = JSON.stringify({id: 1, data: 'foo'})
   ,qstr  = ['MATCH (n %DATUM)'
            ,'RETURN n'
            ].join('\n')
          .replace('%DATUM', enc_datum)
db.query(qstr)

它会抱怨'''字符,因为Cypher接受这样的编码对象:

MATCH (n {id: 1, data: 'foo'})
RETURN n

使用JSON编码的

var enc_datum = JSON.stringify({id: 1, data: 'foo'})
console.log(enc_datum)
// would be {"id":1,"data":"foo"}

错误消息显示,由于"字符,Cypher或Neo4j模块不会使用标准JSON。它会抱怨{之后的下一个字符应为identifier或其他字符。

所以我陷入困境:要么在嵌入查询字符串之前必须使用一些讨厌的RegExpr来处理JSON字符串,要么我必须发明一种方法来编码仅用于小"字符的对象。我只是想问一下,在我进入这两种棘手的方式之前是否有更合适的解决方案......

(我现在在测试中通过使用eval而不是JSON来解决这个问题来评估我的编码数据,而字符串将直接用在Cypher查询中,所以我不能使用JSON对其进行字符串化。但是我无法以这种方式处理客户端编码的JSON)

2 个答案:

答案 0 :(得分:3)

  1. Cypher不使用JSON,它是一种看起来有点像JSON但不使用引号用于键的地图格式
  2. 使用参数代替MATCH (n {props})将实际参数作为值传递
  3. 喜欢这个

    {“query”,“MATCH(n {props})return n”,   “params”:{“props”:{“id”:1,“data”:“foo”}}}

答案 1 :(得分:2)

  

MATCH(n {id:1,data:'foo'})

您似乎使用的格式是JSON5。您可以使用以下代码避免使用双引号:

var jju = require('jju')

jju.stringify({id: 1, data: 'foo'}, {quote:"'"}).replace(/"/g,'\\x22')
// result: "{id: 1, data: 'foo'}" (string)

jju.parse("{id: 1, data: 'foo'}")
// result: {id: 1, data: 'foo'} (object)

请注意两件重要的事情:

  1. “quote”参数确保模块始终使用单引号来包装字符串
  2. replace()确保所有双引号都被编码为\ x22,如果它们恰好位于您的输入中(即数据:'foo“bar')
  3. 我不知道该数据库有什么其他限制,也许用base64或其他东西对它进行编码是值得的。