【问题标题】:How to solve the dilemma while handle JSON in Neo4j Cypher?在 Neo4j Cypher 中处理 JSON 时如何解决困境?
【发布时间】:2013-12-30 14:32:09
【问题描述】:

我发现在编写 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 或其他字符。

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

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

【问题讨论】:

  • 我现在使用这个作为快速修复:enc_datum.replace(/":/g,':').replace(/{"/g,'{').replace(/,"/g,','),我仍然想知道是否有更好的解决方案。

标签: javascript json node.js neo4j


【解决方案1】:

匹配(n {id:1,数据:'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 如果它们恰好在您的输入中(即 data: 'foo"bar')

我不知道该数据库还有什么其他限制,也许值得用 base64 或其他东西对其进行编码。

【讨论】:

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

      {"query","MATCH (n {props}) 返回 n", "params": {"props":{"id":1,"data":"foo"}}}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多