2017-08-11 160 views
2

我想根据用户输入对排序结果进行排序。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 

它工作正常。 但我想按用户排序对象中传递的字段排序结果。 我添加了自定义功能阿朗戈:

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 

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

+0

你有没有看过在ArangoDB内的Foxx Microservices?这是它们的完美应用,让Foxx提供一个REST API,然后用户可以提供Sort,PageNum,PageSize,Query属性,Foxx REST API将为您提供。 –

+0

@DavidThomas你能给我一些实现它的例子吗? – MatiK

+0

看看[这个答案](https://stackoverflow.com/questions/42427063/sending-http-post-request-from-node-to-foxx-service-arangodb/42451340#42451340)我提供了一个如何设置Foxx微服务来响应REST API请求的示例。您可以允许调用者通过路径,查询字符串或主体提供其他查询参数,然后让您的代码调用适当的查询。如何编写Foxx Microservice不在这个问题的范围内,但它遵循Node.js风格的格式,并且在线有很多示例,特别是在github.com中。 –

回答

1

纯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服务器上测试过这些,所以可能存在一些错字。

+0

我不能动态地做到这一点。我有时需要按名称进行排序并创建字段,有时只能通过createdAt进行排序。有太多的排列组合来分别写每个案例。我也想重复使用它与其他查询。我可以编写函数来动态创建这样的字符串,但是当调用db查询时,我不能使用js aql标记。这是一个耻辱有没有简单的方法来做排序与arango :( – MatiK

+0

排序很容易..是否有一个原因,你发送它之前,你不能使用Foxx或动态生成您的AQL –

+0

我不能使用Foxx,因为的客户限制,动态生成的AQL与js aql标签不兼容,它因安全限制而失败,我不希望被注入,如果我自己进行验证,那么总会有一些风险, 。 – MatiK

相关问题