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

Dav*_*mas 7 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 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);
      });
  });
Run Code Online (Sandbox Code Playgroud)

我是Node.js和ArangoDB的新手,并且希望能够使用正确的参数化查询.

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

谢谢!

Ala*_*lum 4

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

FOR t IN @first FILTER t.a == @second RETURN t
Run Code Online (Sandbox Code Playgroud)

在 AQL 集合中,不能使用普通绑定参数注入名称。这是因为您实际上并没有尝试将参数用作字符串值,而是引用具有该名称的集合。引用AQL 文档

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

换句话说,在 AQL 中必须调用它@@first(而不是@first),并且在它的绑定参数参数中db.query必须调用它@first(而不仅仅是first)。

当使用 arangojs 时,实际上可以通过使用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);
});
Run Code Online (Sandbox Code Playgroud)

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

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