简体   繁体   中英

ArangoDB - Sort result in aql with custom function

I'd like to have sorted result depending on user input.

Lets say I have sort object that could look like this:

var sort = {createdAt: -1}

or like this:

var sort = {createdAt: 1, name: 1}

And I have query that looks like this:

FOR f in [{createdAt: 123, name: 'BBB'},{createdAt: 2000, name: 'ZZZ'}, {createdAt: 2000, name: 'BBB'}]
    SORT f.createdAt DESC
    RETURN f

and it works ok. But I'd like to SORT result by field that is passed in sort object by user. I added custom arango function:

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

but when I'm using it that way it doesn't work at all. Result is not sorted in any way:

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

How can I sort result basing on different input arguments?

Pure AQL, you can do this but somewhere in the world a puppy will die...

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

But the other way is to dynamically generate the AQL, with proper code checking you can do it safely.

I sometimes generate AQL dynamically, but all parameters are carefully scanned, cleansed, Joi schema proofed, and validated to stop SQL injection.

The other way of doing this style query is:

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

This isn't pretty, but works, and with creativity you can write heavily nested and complex queries with ASC and DESC as options, as well as a predefined number of column names. Importantly the column names can't by fully dynamic, but can be user selected.

I haven't tested these on an ArangoDB server so some typo's may exist.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM