
人工智能(AI) VS 商業智能(BI) 區別與聯系是什么?
var assert = require('assert');
assert.deepEqual(qs.parse('price[gte]=10&price[lte]=100'), {
price: {
gte: 10,
lte: 100
}
});
GROUP BY
GROUP BY
與括號方法類似,您可以設計一個 API 將運算符置于 RHS(而不是 LHS)上。例如,將查找價格大于或等于 10,但小于或等于 100 的所有商品。 GET /items?price=gte:10&price=lte:100
GET /items?user_id=gt:100
如果您需要在端點上進行搜索,您可以直接使用搜索參數添加對過濾器和范圍的支持。如果您已經在使用 ElasticSearch 或其他基于 Lucene 的技術,您可以直接支持 Lucene 語法或 ElasticSearch 簡單查詢字符串。
例如,我們可以搜索包含術語 red chair 且價格大于或等于 10 且小于或等于 100 的商品: GET /items?q=title:red chair AND price:[10 TO 100]
此類 API 可以允許模糊匹配、增強某些術語等等。
大多數返回實體列表的端點都需要某種分頁。
如果沒有分頁,簡單的搜索可能會返回數百萬甚至數十億的點擊量,從而導致額外的網絡流量。
分頁需要隱式排序。默認情況下,這可能是項目的唯一標識符,但也可以是其他有序字段,例如創建日期。
這是最簡單的分頁形式。限制/偏移在使用 SQL 數據庫的應用程序中變得流行,這些數據庫已經將 LIMIT 和 OFFSET 作為 SQL SELECT 語法的一部分。實現限制/偏移分頁只需要很少的業務邏輯。
限制/偏移分頁看起來像。此查詢將返回從第 100 行開始的 20 行。 GET /items?limit=20&offset=100
(假設查詢按創建日期降序排序)
GET /items?limit=20
GET /items?limit=20&offset=20
GET /items?limit=20&offset=40
作為 SQL 語句,第三個請求如下所示:
SELECT
*
FROM
Items
ORDER BY Id
LIMIT 20
OFFSET 40;
GET /items?offset=0&limit=15
GET /items?offset=15&limit=15
GET /items?offset=25&limit=15
即使有限制,偏移分頁也很容易實現和理解,并且可以用于數據集上限較小的應用程序。
鍵集分頁使用最后一頁的過濾器值來獲取下一組項目。這些列將被索引。
(假設查詢按創建日期降序排序)
GET /items?limit=20
GET /items?limit=20&created:lte:2021-01-20T00:00:00
GET /items?limit=20&created:lte:2021-01-19T00:00:00
SELECT
*
FROM
Items
WHERE
created <= '2021-01-20T00:00:00'
ORDER BY Id
LIMIT 20
鍵集分頁對于具有單個自然高基數鍵的數據非常有效,例如可以使用時間戳的時間序列或日志數據。
查找分頁是鍵集分頁的擴展。通過添加 after_id 或 start_id URL 參數,我們可以消除分頁與過濾器和排序的緊密耦合。由于唯一標識符本質上是高基數,因此我們不會遇到與按低基數字段(如狀態枚舉或類別名稱)排序不同的問題。
基于搜索的分頁的問題是當需要自定義排序順序時很難實現。
(假設查詢按創建日期升序排序)
GET /items?limit=20
GET /items?limit=20&after_id=20
GET /items?limit=20&after_id=40
尋求分頁可以被提煉成一個子句 where
SELECT
*
FROM
Items
WHERE
Id > 20
LIMIT 20
如果按 id 排序,上面的示例可以正常工作,但如果我們想按電子郵件字段排序怎么辦?對于每個請求,后端需要首先獲取標識符與 after_id 匹配的項目的電子郵件值。然后,使用該值作為過濾器執行第二個查詢。 where
讓我們考慮一下查詢,后端將需要兩個查詢。第一個查詢可能是使用哈希表進行 O(1) 查找,以獲得電子郵件數據透視值。將此輸入到第二個查詢中,以僅檢索電子郵件位于 after_email 之后的項目。我們按電子郵件和 ID 兩列進行排序,以確保在兩封電子郵件相同的情況下有穩定的排序。這對于較低基數字段至關重要。 GET /items?limit=20&after_id=20&sort_by=email
1.
SELECT
email AS AFTER_EMAIL
FROM
Items
WHERE
Id = 20
2.
SELECT
*
FROM
Items
WHERE
Email >= [AFTER_EMAIL]
ORDER BY Email, Id
LIMIT 20
Seek 分頁是一個很好的整體分頁策略,也是我們在 Moesif Public API 上實現的。它需要在后端進行更多的工作,但確保不會給 API 的客戶端/用戶增加額外的復雜性,同時即使在更大的搜索范圍內也能保持性能。
與過濾一樣,排序對于任何返回大量數據的 API 端點來說都是一項重要功能。如果您要返回用戶列表,您的 API 用戶可能希望按上次修改日期或電子郵件進行排序。
為了啟用排序,許多 API 添加了 sort 或 sort_by URL 參數,該參數可以將字段名稱作為值。
然而,良好的 API 設計可以靈活地指定升序或降序。與過濾器一樣,指定順序需要將三個組件編碼為鍵/值對。
GET /users?sort_by=asc(email)
和 GET /users?sort_by=desc(email)
GET /users?sort_by=+email
和 GET /users?sort_by=-email
GET /users?sort_by=email.asc
和 GET /users?sort_by=email.desc
GET /users?sort_by=email&order_by=asc
和 GET /users?sort_by=email&order_by=desc
不建議使用排序和順序不配對的最后一種設計。您最終可能允許按兩列或更多列排序:
SELECT
email
FROM
Items
ORDER BY Last_Modified DESC, Email ASC
LIMIT 20
要編碼此多列排序,您可以允許多個字段名稱,例如
GET /users?sort_by=desc(last_modified),asc(email)
或
GET /users?sort_by=-last_modified,+email
如果排序字段和排序不配對,則需要保留 URL 參數排序;否則,什么排序應該與什么字段名稱配對是不明確的。然而,許多服務器端框架在反序列化到映射后可能不會保留順序。
您還必須確保任何緩存鍵都考慮 URL 參數排序,但這會給緩存大小帶來壓力。
良好的 API 設計是開發者體驗 (DX) 的關鍵組成部分。 API 規范可以比許多底層服務器實現更持久,這需要考慮 API 的未來用例。
原文鏈接:REST API Design: Filtering, Sorting, and Pagination