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过这些,所以有些错字可能存在。