当参数未提前知道时,Cypher MATCH请求

时间:2017-02-20 20:46:52

标签: javascript node.js neo4j ecmascript-6 cypher

我试图用javascript实现一种OGM。它不会完全是一个OGM,但它适用于我的项目。 但是我需要能够使用像

这样的方法
User.find({ where : {name:}})

有点像Sequelize会为SQL做的。 但是,如果我试试这个:

run('MATCH (n:User {where}) RETURN ID(n) as id', { where: where });

Cypher回答这个问题:

Parameter maps cannot be used in MATCH patterns 
(use a literal map instead, eg. "{id: {param}.id}")

另一篇文章解释说原因是:

  

"与CREATE中的属性不同,MATCH要求地图为文字。这是因为在编译查询时必须事先知道属性名称,以便有效地规划其执行。"

有人知道如果我没有预先提供属性名称,我可以如何参数化请求? (我的GrapQL API可以接收许多参数)......

非常感谢!

2 个答案:

答案 0 :(得分:2)

有些人喜欢这样:

WITH {where} as params
MATCH (n:User) WHERE ALL(k in keys(params) WHERE params[k] = n[k])
RETURN id(n)

或者,正如@logisma所说 - 在脚本端生成请求:

var params = [];
Object.keys(where).forEach( function(key) {
    var str = "`" + key + "`: " + JSON.stringify( where[key] );
    params.push( str );
});
run('MATCH (n:User {' + params.join(", ") + '}) RETURN ID(n) as id')

答案 1 :(得分:1)

这是一个更简单的@stdob版本 - 第二种方法(这是更可取的,因为如果查询中指定的任何User属性被编入索引,它会更快):

var util = require('util');

run('MATCH (n:User ' + util.inspect(where) + ') RETURN ID(n) as id');

我假设where对象是在inspect调用范围内定义的。