如何对 Trello api 响应进行分页?
How to paginate Trello api response?
我正在使用 Trello 的 API 来拉动看板和它们的卡片。
我注意到我正在拉的其中一个板目前接近千张卡片,所以我想知道如何对结果进行分页?
我尝试使用 since
属性并将最后一张卡片的更新时间输入其中,但之后我得到的结果为零,所以我一定是做错了什么。
api 文档并没有说太多,我试过的 API 响应非常混乱:
/boards/xyz/cards?limit=1&before=2015-1-1
returns activity 是 在 指定日期之后的卡片。
"dateLastActivity"=>"2015-02-03T17:51:23.253Z",
并且没有其他日期字段可以用来继续分页。
您的评价是对的。 before 和 since 参数在卡片创建日期运行。因为我们使用标准 Mongo ID,所以您实际上可以从卡片 ID 中得出卡片创建日期。 (这是一个这样的工具:https://steveridout.github.io/mongo-object-time/)
为方便起见,Trello 还允许您将卡 ID 传递给 before 和 since 参数,我们将为您使用日期。通过大量卡片进行分页的推荐方法是重复相同的查询,并使用这些参数向前或向后移动。
因此,由于 API 确实无法像您期望的那样工作,所以我至少在此处记录了这一点。
我用卡片 A
、B
、C
、...、M
创建了一个测试板,所以我可以在上面进行测试。
首先,抓取所有卡片按预期工作。
api.find(:boards, '56af532ae7a74a5fcac32e66').cards.map { |c| [c.name, c.id] }
=> [
["A", "56af53367f15b163c0e345fd"],
["B", "56af533783d4fccc1cce3941"],
["C", "56af533831727db409451c9e"],
["D", "56af53397bf672bb56c7c536"],
["E", "56af5339f5e67cf6bcc7323b"],
["F", "56af533ac0aa02de54ab881a"],
["G", "56af533b212b095266ebb506"],
["H", "56af533e11992f20f375fca1"],
["I", "56af533fc1775129aaa7028b"],
["J", "56af5345f81227a7a1cc3a35"],
["K", "56af5345e36b3d3c45b16967"],
["L", "56af534d964b6c4aa93d4aca"],
["M", "56af534e768610ff67c781ce"]
]
注意:卡片的顺序不是按照创建时间,而是按照它们在面板中从左列到右列以及从上到下的出现顺序。
限制
好的,是时候开始分页了。我们只拿第一张牌好吗?
board.cards(limit: 1).map { |c| [c.name, c.id] }
=> [["M", "56af534e768610ff67c781ce"]]
糟糕,API return 是最后一个元素。绝对出乎意料。接下来让我们玩after/before。
之前
让我们在最后一个之前抢卡。
board.cards(limit: 1, before: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }
=> [["L", "56af534d964b6c4aa93d4aca"]]
效果不错,L
在M
之前。
之后
如果我们在最后一张之后抓一张牌,响应应该是空的,对吧?
board.cards(limit: 1, after: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }
=> [["M", "56af534e768610ff67c781ce"]]
嗯,什么?那如果我抓两张卡会怎样?
board.cards(limit: 2, after: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }
=> [
["L", "56af534d964b6c4aa93d4aca"],
["M", "56af534e768610ff67c781ce"]
]
这违背了任何逻辑。肯定不能从头到尾遍历一遍,因为卡片列表是没有尽头的。
返回分页
在这种情况下,我们将不得不以相反的顺序检查卡片。只需指定 limit
即可,因为默认情况下我们将按相反的顺序进行。 (这很有意义,对吧?)
api.find(:boards, '56af532ae7a74a5fcac32e66').cards(limit: 5).map { |c| [c.name, c.id] }
=> [
["I", "56af533fc1775129aaa7028b"],
["J", "56af5345f81227a7a1cc3a35"],
["K", "56af5345e36b3d3c45b16967"],
["L", "56af534d964b6c4aa93d4aca"],
["M", "56af534e768610ff67c781ce"]
]
不要让这些项目的顺序欺骗了您!仍然是它们 出现 在面板中的顺序,它们不是按创建时间排序的。如果我在其列中移动 M
卡片,使其正好位于 L
上方,则 API 将按相反的顺序 return 它们。
现在的问题是,如何从列表中抓取旧卡?正如另一个答案所说,ID 是时间戳,所以我们只需按 ID 排序并选择最低的并继续分页。
注意:如果您的速度很快,您可以在同一秒内创建多张卡片,因此 ID 的顺序可能不正确,因为它们只使用秒数,而不是微秒数。但这并不妨碍我们进行分页。
board.cards(limit: 5, before: '56af533fc1775129aaa7028b').map { |c| [c.name, c.id] }
=> [
["D", "56af53397bf672bb56c7c536"],
["E", "56af5339f5e67cf6bcc7323b"],
["F", "56af533ac0aa02de54ab881a"],
["G", "56af533b212b095266ebb506"],
["H", "56af533e11992f20f375fca1"]
]
太棒了,我们正在看下一页,让我们看最后一页吧。
board.cards(limit: 5, before: '56af53397bf672bb56c7c536').map { |c| [c.name, c.id] }
=> [
["A", "56af53367f15b163c0e345fd"],
["B", "56af533783d4fccc1cce3941"],
["C", "56af533831727db409451c9e"]
]
是的,所以最后一页包含的卡片少于限制,所以我们知道它是最后一页。万岁! (如果它等于页面大小,我们会发现下一个响应是空的)
我正在使用 Trello 的 API 来拉动看板和它们的卡片。
我注意到我正在拉的其中一个板目前接近千张卡片,所以我想知道如何对结果进行分页?
我尝试使用 since
属性并将最后一张卡片的更新时间输入其中,但之后我得到的结果为零,所以我一定是做错了什么。
api 文档并没有说太多,我试过的 API 响应非常混乱:
/boards/xyz/cards?limit=1&before=2015-1-1
returns activity 是 在 指定日期之后的卡片。
"dateLastActivity"=>"2015-02-03T17:51:23.253Z",
并且没有其他日期字段可以用来继续分页。
您的评价是对的。 before 和 since 参数在卡片创建日期运行。因为我们使用标准 Mongo ID,所以您实际上可以从卡片 ID 中得出卡片创建日期。 (这是一个这样的工具:https://steveridout.github.io/mongo-object-time/)
为方便起见,Trello 还允许您将卡 ID 传递给 before 和 since 参数,我们将为您使用日期。通过大量卡片进行分页的推荐方法是重复相同的查询,并使用这些参数向前或向后移动。
因此,由于 API 确实无法像您期望的那样工作,所以我至少在此处记录了这一点。
我用卡片 A
、B
、C
、...、M
创建了一个测试板,所以我可以在上面进行测试。
首先,抓取所有卡片按预期工作。
api.find(:boards, '56af532ae7a74a5fcac32e66').cards.map { |c| [c.name, c.id] }
=> [
["A", "56af53367f15b163c0e345fd"],
["B", "56af533783d4fccc1cce3941"],
["C", "56af533831727db409451c9e"],
["D", "56af53397bf672bb56c7c536"],
["E", "56af5339f5e67cf6bcc7323b"],
["F", "56af533ac0aa02de54ab881a"],
["G", "56af533b212b095266ebb506"],
["H", "56af533e11992f20f375fca1"],
["I", "56af533fc1775129aaa7028b"],
["J", "56af5345f81227a7a1cc3a35"],
["K", "56af5345e36b3d3c45b16967"],
["L", "56af534d964b6c4aa93d4aca"],
["M", "56af534e768610ff67c781ce"]
]
注意:卡片的顺序不是按照创建时间,而是按照它们在面板中从左列到右列以及从上到下的出现顺序。
限制
好的,是时候开始分页了。我们只拿第一张牌好吗?
board.cards(limit: 1).map { |c| [c.name, c.id] }
=> [["M", "56af534e768610ff67c781ce"]]
糟糕,API return 是最后一个元素。绝对出乎意料。接下来让我们玩after/before。
之前
让我们在最后一个之前抢卡。
board.cards(limit: 1, before: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }
=> [["L", "56af534d964b6c4aa93d4aca"]]
效果不错,L
在M
之前。
之后
如果我们在最后一张之后抓一张牌,响应应该是空的,对吧?
board.cards(limit: 1, after: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }
=> [["M", "56af534e768610ff67c781ce"]]
嗯,什么?那如果我抓两张卡会怎样?
board.cards(limit: 2, after: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }
=> [
["L", "56af534d964b6c4aa93d4aca"],
["M", "56af534e768610ff67c781ce"]
]
这违背了任何逻辑。肯定不能从头到尾遍历一遍,因为卡片列表是没有尽头的。
返回分页
在这种情况下,我们将不得不以相反的顺序检查卡片。只需指定 limit
即可,因为默认情况下我们将按相反的顺序进行。 (这很有意义,对吧?)
api.find(:boards, '56af532ae7a74a5fcac32e66').cards(limit: 5).map { |c| [c.name, c.id] }
=> [
["I", "56af533fc1775129aaa7028b"],
["J", "56af5345f81227a7a1cc3a35"],
["K", "56af5345e36b3d3c45b16967"],
["L", "56af534d964b6c4aa93d4aca"],
["M", "56af534e768610ff67c781ce"]
]
不要让这些项目的顺序欺骗了您!仍然是它们 出现 在面板中的顺序,它们不是按创建时间排序的。如果我在其列中移动 M
卡片,使其正好位于 L
上方,则 API 将按相反的顺序 return 它们。
现在的问题是,如何从列表中抓取旧卡?正如另一个答案所说,ID 是时间戳,所以我们只需按 ID 排序并选择最低的并继续分页。
注意:如果您的速度很快,您可以在同一秒内创建多张卡片,因此 ID 的顺序可能不正确,因为它们只使用秒数,而不是微秒数。但这并不妨碍我们进行分页。
board.cards(limit: 5, before: '56af533fc1775129aaa7028b').map { |c| [c.name, c.id] }
=> [
["D", "56af53397bf672bb56c7c536"],
["E", "56af5339f5e67cf6bcc7323b"],
["F", "56af533ac0aa02de54ab881a"],
["G", "56af533b212b095266ebb506"],
["H", "56af533e11992f20f375fca1"]
]
太棒了,我们正在看下一页,让我们看最后一页吧。
board.cards(limit: 5, before: '56af53397bf672bb56c7c536').map { |c| [c.name, c.id] }
=> [
["A", "56af53367f15b163c0e345fd"],
["B", "56af533783d4fccc1cce3941"],
["C", "56af533831727db409451c9e"]
]
是的,所以最后一页包含的卡片少于限制,所以我们知道它是最后一页。万岁! (如果它等于页面大小,我们会发现下一个响应是空的)