Jan*_*ovs 5 filter limit amazon-dynamodb aws-amplify
代码示例:
import { API, graphqlOperation } from "aws-amplify"
const fetchInitialAds = () => {
const { filterAttributes } = useContext(FilterContext)
const {
query: { slug },
} = useRouter()
const fetchAds = async ({ pageParam = null }) => {
const {
deal_type,
priceFrom,
priceTo,
} = filterAttributes
const currTimeInSeconds = Math.ceil(Date.now() / 1000)
const options = {
subcategoryID: `SUBCATEGORY#${slug}`,
sortDirection: "DESC",
limit: 24,
nextToken: pageParam,
filter: {
and: [
{
or: [
{
list_price: {
between: [
Number(priceFrom) || 0,
Number(priceTo) || 100000000,
],
},
},
{
new_price: {
between: [
Number(priceFrom) || 0,
Number(priceTo) || 100000000,
],
},
},
],
},
],
},
}
const adsResult = await API.graphql(
graphqlOperation(adsBySubcategoryByExpdate, options)
)
const data = await adsResult.data.adsBySubcategoryByExpdate
return data
}
return useInfiniteQuery(["ads", slug], fetchAds, {
getNextPageParam: (currentPage, allPages) => currentPage.nextToken,
})
}
Run Code Online (Sandbox Code Playgroud)
在大型数据库上使用“限制”+“过滤器”进行“查询”时出现问题,例如其中包含 5000 个项目。如果您限制为一次显示 24 个项目(用于分页),则“过滤器”表达式将仅过滤表中的前 24 个项目并返回匹配的项目。如果您对 24 个第一个项目中的 5 个进行过滤匹配,它将仅返回这 5 个项目... <-- 这意味着您要向客户端显示的第一页将不完整,只有 24 个项目,而只有 5 个项目。 .然后您需要使用“nextToken”再次过滤接下来的 24 个项目。这次也许你会得到 10 件匹配的物品。所以现在您只向客户显示 16 个项目(仍然不是 24 个项目的整页......)。假设第三次运行接下来的 24 个项目,您将获得 0 个匹配的项目 <-- 您将不会获得任何新项目来显示您的客户。这会感觉很奇怪 - 您单击按钮来获取接下来的 24 个项目,但获得了 0 个项目,并且您必须继续单击该按钮,直到它遇到一些新的匹配项目,直到您浏览完整个表......
所以我的问题是:是否有一种解决方案,如果您设置 24 个项目的限制,以便 dynamo db 收集 24 个匹配项目的完整列表,然后只返回整个页面?我不想得到半满的页面并垃圾邮件我的“获取更多”按钮,看看我是否没有错过任何其他过滤器匹配的项目......
事实上,Query操作首先读取一页数据(1MB 数据,Limit如果指定该参数则为行),然后才对其进行过滤,这是经过深思熟虑并记录在案的:
单个
Query操作将读取最多设置的最大数量的项目(如果使用该Limit参数)或最多 1 MB 的数据,然后使用对结果应用任何过滤FilterExpression。...如果结果页读取的所有项目都被过滤掉,则Query操作可以返回空结果集和 a 。LastEvaluatedKey
这种设计的原因是它限制了每个请求的延迟和成本:想象一下这样一种情况,在 1 TB 数据库中,您使用仅匹配 5 个项目的过滤器运行查询。如果查询继续直到可以返回 5 个项目,则它可能会在返回任何内容之前读取 1 TB 的数据 - 这将导致巨大的延迟(客户端很可能会假设连接已中断并在获得响应之前断开连接...... )以及巨大的成本。通过每次数据库读取 1 MB 数据时返回一个空页,客户端始终知道查询正在进行并且不会超时,并且还始终了解此查询的成本并有机会停止它。
人们可以想象一个更好的 API,其中包括对要读取的项目数量的限制,以及对要返回的项目的限制,一旦达到这些限制中的任何一个,页面就会结束。不幸的是,DynamoDB 没有这样的 API。Limit正如您所注意到的,如果没有返回足够的结果,您将被迫使用 a并重试。
如果您认为匹配结果在项目之间均匀分布,您可以尝试“猜测”Limit 应该有多大才能产生大致正确数量的结果 - 并且您可以在进行过程中改进这种猜测。猜测太低的 Limit 仅意味着您需要发出第二个查询,而猜测太高的 Limit 仅意味着您会读得太多(并且付出了太多),但无论哪种情况都是(通常)不是灾难。在任何情况下,您都不需要用户单击来获取更多结果 - 您可以在代码内部完成此操作。
| 归档时间: |
|
| 查看次数: |
1224 次 |
| 最近记录: |