Arangodb 使用arangojs将参数传递给db.query

Arangodb 使用arangojs将参数传递给db.query,arangodb,Arangodb,我在ArangoJS库中发送参数时遇到问题,不知道是否有人可以帮助我 在下面的示例中,如果查询中包含参数值,则可以执行db.query,但只要我尝试使用bindVars,就会出现无声错误,并且无法提取任何错误详细信息 var db = require('arangojs')("http://127.0.0.1:8529"); /* The '_system' database contains a collection called 'test' that contains one docum

我在ArangoJS库中发送参数时遇到问题,不知道是否有人可以帮助我

在下面的示例中,如果查询中包含参数值,则可以执行db.query,但只要我尝试使用bindVars,就会出现无声错误,并且无法提取任何错误详细信息

var db = require('arangojs')("http://127.0.0.1:8529");

/*
The '_system' database contains a collection called 'test' that contains one document:
 {
   "a": 1,
   "b": 2
 }
 */

// This works
db.query('FOR t IN test FILTER t.a == 1 RETURN t')
  .then((cursor) => {
    cursor.all()
      .then(vals => {
        console.log("\nNo bindVars");
        console.log(vals);
      });
  });

// This does not work
db.query("FOR t IN @first FILTER t.a == @second RETURN t", { first: "test", second: 1 })
  .then((cursor) => {
    cursor.all()
      .then(vals => {
        console.log("\nUsing bindVars");
        console.log(vals);
      });
  });
我不熟悉Node.js和ArangoDB,希望能够使用正确的参数化查询

我还假设使用参数可以保护您免受SQL注入式攻击


谢谢

问题不在于JavaScript驱动程序或节点,而在于查询本身:

FOR t IN @first FILTER t.a == @second RETURN t
在AQL集合中,不能使用普通绑定参数注入名称。这是因为您实际上并没有尝试将参数用作字符串值,而是引用具有该名称的集合。引述:

存在用于注入集合名称的特殊类型的绑定参数。这种类型的bind参数的名称前缀有一个额外的@符号(因此,在查询中使用bind参数时,必须使用两个@符号)

换句话说,在AQL中,它必须被称为
@@first
(而不是
@first
),并且在绑定参数参数到
db.query
中,它必须被称为
@first
(而不仅仅是
first

使用arangojs时,实际上可以通过使用以下命令完全避免这种情况:

这样,在编写查询时就不必考虑绑定参数语法,并且可以编写更复杂的查询,而不必处理非常长的字符串。注意,它将识别arangojs集合实例并相应地处理它们。使用字符串而不是集合实例将导致与示例中相同的问题


另外请注意,模板处理程序也存在于arangosh shell和ArangoDB本身中(例如,在使用Foxx时)。

非常感谢@Alan,它现在为我工作。这有助于解释查询ArangoDb的不同方式,顺便说一句,我很喜欢ArangoDb。再次感谢。请快速跟进问题的SQL注入攻击保护部分,对于用户的输入,是否最好使用基于标准db.query的参数,因为最终用户可以将代码注入模板字符串?@DavidThomas,模板处理程序实际上插入变量名,并生成一个查询和一个将名称映射到参数的绑定对象。结果与手动操作相同。只有手动生成字符串(通过连接或使用未使用aqlQuery模板处理程序的原始模板字符串)时,才会发生注入攻击。
var aqlQuery = require('arangojs').aqlQuery;
var first = db.collection('test');
var second = 1;

db.query(aqlQuery`
  FOR t IN ${first}
  FILTER t.a == ${second}
  RETURN t
`).then(
  cursor => cursor.all()
).then(vals => {
  console.log('Using aqlQuery');
  console.log(vals);
});