【问题标题】:How to get past SharePoint Online 5000 row limit restriction with Caml?如何通过 Caml 克服 SharePoint Online 5000 行限制限制?
【发布时间】:2019-11-30 15:30:17
【问题描述】:

使用 Caml,我试图从 SharePoint Online 网站中撤回去年已修改的所有项目。查询导致错误指出:“禁止尝试的操作,因为它超出了管理员强制执行的列表视图阈值。”此阈值是 SharePoint Online 上的 5000 个项目,据我与 SharePoint 管理员讨论后无法修改。

这个错误有据可查,但我看过的解决方案都没有解决我的问题。

我以前通过在我的 Caml 查询中使用 <RowLimit></RowLimit> 标记并设置一个 $position 变量来跟踪我在每块 5000 个项目之后的位置,从而解决了这个问题。有关适用于超过 5000 个项目的列表的查询,请参见下文:

$query = @"
<View Scope="RecursiveAll">
    <Query>
        <OrderBy><FieldRef Name="Created" Ascending="false"/></OrderBy>
    </Query>
    <RowLimit Paged="TRUE">5000</RowLimit>
</View>
"@

以上工作。但是,它只是从某个库中获取所有内容。我现在要做的是获取过去一年中修改过的所有内容。这是我所拥有的:

$oneYearAgo = (Get-Date).AddDays(-365)
$oneYearAgoString = $oneYearAgo.ToString("yyyy-MM-ddTHH:mm:ssZ")

$query = @"
<View Scope='RecursiveAll'>
    <Query>
        <OrderBy><FieldRef Name='Modified' Ascending='false'/></OrderBy>
        <Where>
            <Geq>
                <FieldRef Name="Modified"/>
                <Value Type="DateTime">
                    $oneYearAgoString
                </Value>
            </Geq>
        </Where>
    </Query>
    <RowLimit Paged="TRUE">5000</RowLimit>
</View>
"@

此返回“尝试的操作被禁止,因为它超出了管理员强制执行的列表视图阈值”错误,尽管两个 Caml 查询之外的逻辑几乎相同。

我的 Caml 查询有问题吗?

【问题讨论】:

  • Modified 列是否已编入索引?您可以在列表设置页面的列部分底部找到列表的索引列。
  • 我遇到了我们的一位 SharePoint 管理员,但该列尚未编入索引。但现在是这样,不幸的是,我们仍然看到同样的错误。

标签: powershell sharepoint sharepoint-online caml


【解决方案1】:

选项 1:创建一个 filtered List View 以获取低于 5000 的项目数。然后,获取该特定视图上的项目。

选项 2:在不查询的情况下获取项目集合中的所有项目。然后,使用 Linq 查询项目集合。您可以参考here 在 PowerShell 中使用 Linq。像这样的:

$FilteredItems = $ItemCollection.Where({($_.Modified-eq $oneYearAgoString)

【讨论】:

  • 感谢您的回答!我不认为第一种选择对我们来说是可行的,但我会更多地探索第二种选择。我以前没有使用过 Linq,所以我很感激这个提示!
【解决方案2】:

我建议您使用查询的“ListItemCollectionPosition”字段。因此,您可以创建一个递归方法并遍历整个列表(即使它包含超过 5000 个项目)。

public static List<SharePointNode> GetDocumentsByCaml(ClientContext localCTX, List list, SharePointNode spCurrentNode, ListItemCollectionPosition position = null)
    {
        List<SharePointNode> lstDocuments = new List<SharePointNode>();
        try
        {
            CamlQuery camlQuery = new CamlQuery();
            camlQuery.ViewXml = @"<View Scope='Recursive'><Query>
                                   <Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>0</Value></Eq></Query><RowLimit>1000</RowLimit></View>";

            camlQuery.ListItemCollectionPosition = position;
            camlQuery.FolderServerRelativeUrl = spCurrentNode.URL;

            ListItemCollection listItems = list.GetItems(camlQuery);
            localCTX.Load(listItems);
            localCTX.Load(listItems, a => a.Include(item => item.File, 
                                                    item => item.File.CheckedOutByUser, 
                                                    item => item.File.CheckOutType));
            localCTX.ExecuteQuery();

            foreach (ListItem itemOfInterest in listItems)
            {
                SharePointNode spNodeDoc = new SharePointNode();
                // check here every listItem and compare the last modified date
                // if it was modified in the past year -> put it into your result list.

                lstDocuments.Add(spNodeDoc);
            }

            if (listItems.ListItemCollectionPosition != null)
            {
                lstDocuments.AddRange(GetDocumentsByCaml(localCTX, list, spCurrentNode, listItems.ListItemCollectionPosition));
            }
        }
        catch (Exception ex)
        {
            // log the message
        }

        return lstDocuments;
    }

【讨论】:

  • 附加信息:SharePointNode 是我自己的课程
  • 感谢您的回答,马克斯。可悲的是,这就是我已经在做的事情。此过程适用于我上面问题中的第一个 Caml 查询,但不适用于我的第二个查询。
猜你喜欢
  • 1970-01-01
  • 2020-05-07
  • 2021-09-23
  • 2019-02-08
  • 1970-01-01
  • 2023-03-13
  • 2016-02-08
  • 2013-04-22
  • 2016-07-10
相关资源
最近更新 更多