如何用REST API获取超阈值SharePoint文件夹的文件与元数据
问题背景
从包含7000个文件和子文件夹的SharePoint库文件夹中获取数据,使用以下REST查询时触发了列表视图阈值错误:
"/_api/Web/GetFolderByServerRelativePath(decodedurl='" + ListName + "')?$select=ID,EncodedAbsUrl,File_x0020_Type&$expand=Folders,Folders/ListItemAllFields/HasUniqueRoleAssignments,Files/ModifiedBy/Title,Files/ListItemAllFields/HasUniqueRoleAssignments,Folders/ListItemAllFields,Files,Files/ListItemAllFields,Files/ListItemAllFields/FileSizeDisplay&$orderby=Modified desc";
尝试以下修改后仍无法解决:
- 使用索引列
CustomID过滤,查询如下:
"/_api/Web/GetFolderByServerRelativeUrl('" + ListName + "')?$select=ID,CustomID,EncodedAbsUrl,File_x0020_Type&$expand=Folders,Folders/ListItemAllFields/HasUniqueRoleAssignments,Files/ModifiedBy/Title,Files/ListItemAllFields/HasUniqueRoleAssignments,Folders/ListItemAllFields,Files,Files/ListItemAllFields,Files/ListItemAllFields/FileSizeDisplay&$filter=CustomID gt '8316' and CustomID lt '8318'&$orderby=CustomID desc";
- 添加
$top=5限制返回数量,查询如下:
"/_api/Web/GetFolderByServerRelativePath(decodedurl='" + ListName + "')?$select=ID,EncodedAbsUrl,File_x0020_Type&$expand=Folders,Folders/ListItemAllFields/HasUniqueRoleAssignments,Files/ModifiedBy/Title,Files/ListItemAllFields/HasUniqueRoleAssignments,Folders/ListItemAllFields,Files,Files/ListItemAllFields,Files/ListItemAllFields/FileSizeDisplay&$top=5";
原因分析
- 多展开字段引发隐式全量扫描:查询同时展开
Folders和Files的多层关联字段(如ListItemAllFields、ModifiedBy),SharePoint处理这类嵌套展开时,会对关联列表项执行额外查询,即使加了过滤或$top参数,底层仍可能扫描超过阈值的条目。 - 索引列未作用于核心数据集:虽用索引列
CustomID过滤,但因查询同时覆盖文件夹和文件的关联数据,过滤条件无法覆盖所有隐式子查询,导致部分子查询仍触发阈值。 - 文件夹层级的阈值触发逻辑:直接通过
GetFolderByServerRelativePath获取所有子项时,SharePoint会先扫描该文件夹下的全量内容,再执行截断或过滤,即便加$top也无法避免前期的全量扫描。
解决方案
1. 拆分查询,分别获取文件夹与文件
避免同时展开Folders和Files,拆分两个独立查询,降低单次查询的复杂度:
- 获取文件夹数据:
"/_api/Web/GetFolderByServerRelativePath(decodedurl='" + ListName + "')/Folders?$select=ID,EncodedAbsUrl,File_x0020_Type&$expand=ListItemAllFields/HasUniqueRoleAssignments,ListItemAllFields&$orderby=Modified desc&$top=5000";
- 获取文件数据:
"/_api/Web/GetFolderByServerRelativePath(decodedurl='" + ListName + "')/Files?$select=ID,EncodedAbsUrl,File_x0020_Type&$expand=ModifiedBy/Title,ListItemAllFields/HasUniqueRoleAssignments,ListItemAllFields,ListItemAllFields/FileSizeDisplay&$orderby=Modified desc&$top=5000";
说明:使用$top=5000(REST单页最大返回数),通过@odata.nextLink实现分页获取剩余数据。
2. 让索引列直接作用于目标数据集
针对文件或文件夹的索引字段,明确在对应集合上应用过滤,确保索引被有效调用:
- 带索引过滤的文件查询:
"/_api/Web/GetFolderByServerRelativePath(decodedurl='" + ListName + "')/Files?$select=ID,CustomID,EncodedAbsUrl,File_x0020_Type&$expand=ModifiedBy/Title,ListItemAllFields/HasUniqueRoleAssignments,ListItemAllFields,ListItemAllFields/FileSizeDisplay&$filter=ListItemAllFields/CustomID gt '8316' and ListItemAllFields/CustomID lt '8318'&$orderby=ListItemAllFields/CustomID desc";
注意:需明确指定过滤的是文件对应列表项的CustomID,而非文件夹的字段。
3. 直接查询文档库列表项
通过FileDirRef字段过滤目标文件夹内容,利用索引优化查询:
"/_api/Web/Lists/GetByTitle('" + ListName + "')/Items?$select=ID,EncodedAbsUrl,File_x0020_Type,FileDirRef,Modified,FileSizeDisplay&$expand=ModifiedBy/Title,File,Folder&$filter=FileDirRef eq '" + FolderServerRelativeUrl + "'&$orderby=Modified desc&$top=5000";
说明:确保FileDirRef或用于过滤的字段已添加索引,让查询直接通过索引扫描获取数据。
4. 精简不必要的展开字段
移除查询中不需要的关联字段(如非必需的HasUniqueRoleAssignments),减少底层隐式查询的数量,降低整体查询负载。
内容的提问来源于stack exchange,提问作者BhawnaSingh
相关产品推荐
相关产品推荐

