ArangoDB – 用自定义函数在aql中sorting结果

我想根据用户input有sorting的结果。

比方说,我有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 

它工作正常。 但是我想按字段sorting结果由用户在sorting对象中传递。 我添加了自定义arangofunction:

 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(', ') : ''; }) ); 

但是当我以这种方式使用它时根本不起作用。 结果没有以任何方式sorting:

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

如何根据不同的input参数对结果进行sorting?

纯粹的AQL,你可以做到这一点,但世界上的某个地方小狗将死亡…

 RETURN (@sortBy == 'createdAt' ? (FOR d IN @@collectionName SORT createdAt DESC RETURN d) : (@sortBy == 'name' ? (FOR d in @@collectionname SORT name DESC RETURN d) ) ) ) 

但另一种方式是dynamic生成AQL,通过正确的代码检查,您可以安全地执行此操作。

我有时会dynamic生成AQL,但所有参数都经过仔细扫描,清理,Joi架构validation,并validation以停止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编写嵌套和复杂的查询作为选项,以及预定义的列名称数量。 重要的是,列名不能完全dynamic,但可以被用户select。

我还没有在ArangoDB服务器上testing过这些,所以有些错字可能存在。

Interesting Posts