2017-08-11 77 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

相關問題