Javascript ArangoDB-使用自定义函数在aql中排序结果

Javascript ArangoDB-使用自定义函数在aql中排序结果,javascript,node.js,arangodb,aql,Javascript,Node.js,Arangodb,Aql,我希望根据用户输入对结果进行排序 假设我有一个sort对象,它看起来像这样: var sort = {createdAt: -1} var sort = {createdAt: 1, name: 1} FOR f in [{createdAt: 123, name: 'BBB'},{createdAt: 2000, name: 'ZZZ'}, {createdAt: 2000, name: 'BBB'}] SORT f.createdAt DESC RETURN f 或者像

我希望根据用户输入对结果进行排序

假设我有一个
sort
对象,它看起来像这样:

var sort = {createdAt: -1}
var sort = {createdAt: 1, name: 1}
FOR f in [{createdAt: 123, name: 'BBB'},{createdAt: 2000, name: 'ZZZ'}, {createdAt: 2000, name: 'BBB'}]
    SORT f.createdAt DESC
    RETURN f
或者像这样:

var sort = {createdAt: -1}
var sort = {createdAt: 1, name: 1}
FOR f in [{createdAt: 123, name: 'BBB'},{createdAt: 2000, name: 'ZZZ'}, {createdAt: 2000, name: 'BBB'}]
    SORT f.createdAt DESC
    RETURN f
我有这样一个查询:

var sort = {createdAt: -1}
var sort = {createdAt: 1, name: 1}
FOR f in [{createdAt: 123, name: 'BBB'},{createdAt: 2000, name: 'ZZZ'}, {createdAt: 2000, name: 'BBB'}]
    SORT f.createdAt DESC
    RETURN f
它工作正常。 但我想按用户在SORT对象中传递的字段对结果进行排序。 我添加了自定义arango函数:

db.createFunction(
    'CUSTOM::FILTERING::SORT_STRING',
            String(function (sort, it) {
                    return sort && Object.keys(sort).length !== 0 && sort.constructor === Object ? Object.keys(sort).map(key => `${it}.${key} ${sort[key] >= 0 ? 'ASC' : 'DESC'}`).join(', ') : '';
            })
        );
但当我这样使用它时,它根本不起作用。结果不会以任何方式排序:

FOR f in [{createdAt: 123, name: 'BBB'},{createdAt: 2000, name: 'ZZZ'}, {createdAt: 2000, name: 'BBB'}]
    SORT CUSTOM::FILTERING::SORT_STRING(${sort}, 'f')
    RETURN f

如何根据不同的输入参数对结果进行排序?

纯AQL,您可以这样做,但在世界的某个地方,小狗会死

RETURN (@sortBy == 'createdAt' ?
  (FOR d IN @@collectionName
    SORT createdAt DESC
    RETURN d) : (@sortBy == 'name' ?
      (FOR d in @@collectionname
        SORT name DESC
        RETURN d)
    )
  )
)
但另一种方法是动态生成AQL,通过适当的代码检查,您可以安全地执行

我有时动态生成AQL,但所有参数都经过仔细扫描、清理、Joi模式验证和验证,以停止SQL注入

执行此样式查询的另一种方法是:

LET sortByCreatedAt = (
  FOR d in @@collectionName
    SORT createdAt DESC
    RETURN d)

LET sortByName = (
  FOR d in @@collectionName
    SORT name DESC
    RETURN d)

RETURN (@sortBy == 'createdAt') ? sortByCreatedAt : sortByName
这并不漂亮,但很管用,有了创造力,您可以编写大量嵌套的复杂查询,使用ASC和DESC作为选项,以及预定义数量的列名。重要的是,列名不能完全动态显示,但可以由用户选择


我还没有在ArangoDB服务器上测试过这些,所以可能存在一些打字错误。

您看过ArangoDB中的Foxx Microservices吗?这是它们的完美应用,让Foxx呈现一个restapi,然后用户可以提供Sort、PageNum、PageSize、,查询属性和Foxx REST API将为您完成此任务。@DavidThomas您能给我一些实现它的示例吗?看看我在哪里提供了一个如何设置Foxx microservice以响应REST API请求的示例。您可以允许调用方通过路径、查询字符串或正文提供额外的查询参数,然后让代码调用适当的查询。如何编写Foxx微服务超出了这个问题的范围,但它遵循Node.js样式的格式,并且在线上有很多示例,尤其是在github.com中。@DavidThomas不幸的是,Foxx不是我的选择。有没有办法用自定义函数来实现这一点?他们正在远离自定义函数,而偏爱Foxx。很抱歉听到Foxx不能为您工作,我无法从纯自定义函数的角度回答您的问题。我使用Foxx微服务来做这件事。我不能不动态地做。我有时需要按名称和createdAt字段排序,有时只按createdAt排序。排列太多,无法单独编写每个案例。我还想将它与其他查询一起重用。我可以编写动态创建此类字符串的函数,但在调用db查询时无法使用js aql标记。遗憾的是,没有简单的方法与arango进行排序:(排序很简单..有什么原因不能在发送之前使用Foxx或动态生成AQL吗?我不能使用Foxx,因为客户端限制。动态生成的AQL不能与js AQL标记一起使用。由于安全限制,它失败了。我不想成为注射的受害者。如果我自己验证,则存在alw我可能会错过一些重要的东西。你有没有在@collection sort d中尝试过类似于
的方法对d进行排序@mysort@direction return d
?@mysort是排序的关键,@direction是'asc'或'desc'Yas。如果有固定数量的字段进行排序,它会起作用。但是如果我有不同数量的字段进行排序,并且具有不同的方向,它会起作用不工作:(