CAML 查询:如何从结果集中过滤文件夹?

发布于 2024-07-09 12:06:49 字数 146 浏览 3 评论 0原文

我使用 caml 查询来选择用户修改或添加的所有文档。 查询在指定网站集的所有子网站上递归运行。

现在的问题是我无法删除也是结果集一部分的文件夹。 现在我正在从结果数据表中过滤它们。 但我想知道:是否可以仅使用 caml 从结果集中过滤掉文件夹?

I'm using caml query to select all documents which were modified or added by user. Query runs recursively on all subsites of specified site collection.

Now problem is I can't get rid of folders which are also part of result set. For now I'm filtering them from result datatable. But I'm wondering: Is it possible to filter out folders from result set just by using caml?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

你丑哭了我 2024-07-16 12:06:49

这个 CAML 实际上做到了这一点:

<Where>
    <Eq>
        <FieldRef Name='FSObjType' />
        <Value Type='Integer'>0</Value>
    </Eq>
</Where>

它不会给你任何文件夹。

This CAML actually does the trick:

<Where>
    <Eq>
        <FieldRef Name='FSObjType' />
        <Value Type='Integer'>0</Value>
    </Eq>
</Where>

that will not give you any folders.

会发光的星星闪亮亮i 2024-07-16 12:06:49

所以,我想通了:)
您可以在 caml 查询中使用 FieldRef='ContentType' 并指定要选择或从选择中排除的内容类型的类型。

因此,就我而言,我已将此条件添加到我的 caml 表达式中:

Folder< /Neq>

注意:
多语言设置存在问题。 内容类型的名称可以不同,因此最好从资源中获取内容类型的名称

更新:

看起来我的假设太快了。 我需要根据文件夹内容类型过滤掉所有内容类型,因为在我们的项目中使用了此类内容类型:(

我无法在 caml 中创建可行的查询,因此我将视图字段元素添加到我的查询中,该查询选择列表的 ContentTypeId item 和我过滤掉基于文件夹内容类型的行。

执行此操作的代码很简单,但令我困扰的是,这种简单的任务无法通过纯 caml 完成。

So, i figured it out :)
You can use FieldRef='ContentType' in your caml query and specify typr of content type which you want to select or exclude from select.

So in my case I've added this condition to my caml expression:

<Neq><FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value></Neq>

NOTE:
There are problems in multi language setup. Name of content type can be different, so it is good to get names of content types from resources

UPDATE:

It looks like I was too quick in my assumptions. I need to filter out all contett types based on folder content type, because in our projects such content types are used :(

I was not able to create workable query in caml, so I added view field element to my query which selects ContentTypeId of list item and I filter-out rows which are based on folder content type.

Code to do this is trivial, but it bothers me that such simple task cannot be done by pure caml.

冬天旳寂寞 2024-07-16 12:06:49

根据 CAML Designer 的输出(由 Karine Bosch 和 Andy Van Steenbergen 创建并由Belux 信息工作者用户组)正确的 CAML 语法是:

<Where>
  <Eq>
    <FieldRef Name='FSObjType' />
    <Value Type='Integer'>0</Value>
  </Eq>
</Where>
<QueryOptions>
  <ViewAttributes Scope='RecursiveAll' />
</QueryOptions>

我在 PowerShell 中对此进行了测试并得到了预期结果:

$qry = new-object Microsoft.SharePoint.SPQuery
$qry.Query = "<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>0</Value></Eq></Where><QueryOptions><ViewAttributes Scope='RecursiveAll' /></QueryOptions>"

$items = $lib.GetItems($qry)
$items.Count

您可以将 CAML 中的 标记替换为 SPQuery 对象属性 ViewAttributes 如果您更喜欢,即 $qry.ViewAttributes = “Scope='RecursiveAll'"

测试时请确保每次都重新实例化 SPQuery 对象,因为您无法简单地重新分配 Query 属性。一旦查询已执行,分配给 Query 属性的任何新值都将被忽略,因此执行整个 PowerShell 片段。

According to the output from CAML Designer (created by Karine Bosch and Andy Van Steenbergen and distributed by the Belux Information Worker User Group) the correct CAML syntax is:

<Where>
  <Eq>
    <FieldRef Name='FSObjType' />
    <Value Type='Integer'>0</Value>
  </Eq>
</Where>
<QueryOptions>
  <ViewAttributes Scope='RecursiveAll' />
</QueryOptions>

I tested this in PowerShell and got the expected result:

$qry = new-object Microsoft.SharePoint.SPQuery
$qry.Query = "<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>0</Value></Eq></Where><QueryOptions><ViewAttributes Scope='RecursiveAll' /></QueryOptions>"

$items = $lib.GetItems($qry)
$items.Count

You can replace the <QueryOptions> tag in the CAML with the SPQuery object property ViewAttributes if you prefer, ie $qry.ViewAttributes = “Scope=’RecursiveAll’".

When testing this be sure to re-instantiate the SPQuery object each time as you cannot simple reassign the Query property. Once the query has been executed, any new value assigned to the Query property is ignored. So execute the entire PowerShell fragment.

情魔剑神 2024-07-16 12:06:49

如果您正在使用文件夹并且使用 SPQuery 对象,您可能还需要使用 ViewAttributes 字段来允许递归项目检索。 将值设置为 Scope="Recursive" 将从子文件夹中检索项目,但不会检索结果集中的文件夹对象。

myQuery.ViewAttributes = "Scope=\"Recursive\"";

If you're working with folders and you're using an SPQuery object you also may want to use the ViewAttributes field to allow for recursive item retrieval. Setting the value to Scope="Recursive" will retrieve items from subfolders and will not retrieve the folder objects in the result set.

myQuery.ViewAttributes = "Scope=\"Recursive\"";
眼眸 2024-07-16 12:06:49

我想到了:

<Where>
  <BeginsWith><FieldRef Name="ContentTypeId" />
    <Value Type="ContentTypeId">0x0101</Value>
  </BeginsWith>
</Where>

Dave T.的答案对我来说不起作用,但将其作为灵感, 主要问题是我们只能知道网站级别的 ContentTypeId,因为当内容类型添加到列表/库时,它会变成列表内容类型,并且其 ID 为附加另一个 GUID (0x010100...)。 而且 CAML 中没有 NotBeginsWith 条件,因此我们无法过滤掉文件夹,但我们可以包含网站内容类型 ID 为 0x0101仅文档

具有 FSObjType 字段的解决方案对我不起作用,因为我的库的文件数量远远超过阈值,因此查询中的所有字段都必须建立索引,而且我还没有找到为此建立索引的方法场地。

Dave T.'s answer didn't work for me but taking it as an inspiration here's what I came up with:

<Where>
  <BeginsWith><FieldRef Name="ContentTypeId" />
    <Value Type="ContentTypeId">0x0101</Value>
  </BeginsWith>
</Where>

The main problem is that we can only know ContentTypeId on a site level, because when a content type gets added to a list/library it becomes a list content type and its ID is appended with another GUID (0x010100...). And there's no NotBeginsWith condition in CAML, so we can not filter out folders, but we can include documents only which site content type id is 0x0101.

The solutions with FSObjType field don't work for me because I have libraries with far more files than a threshold so all the fields in the query must be indexed and I haven't found a way to index this field.

回忆凄美了谁 2024-07-16 12:06:49

这对我有用

   <Where>
      <Eq>
         <FieldRef Name='FSObjType' />
         <Value Type='Number'>1</Value>
      </Eq>
   </Where>

This is what worked for me

   <Where>
      <Eq>
         <FieldRef Name='FSObjType' />
         <Value Type='Number'>1</Value>
      </Eq>
   </Where>
骄傲 2024-07-16 12:06:49

检查我的其他答案 在结果集中包含文件夹的 CAML 查询

简单地更改运算符可能会满足您的需要,

<Where>
  <NotIncludes>
    <FieldRef Name='ContentTypeId' />
    <Value Type='ContentTypeId'>0x0120</Value>
  </NotIncludes>
</Where>

我不确定这是否有效。

Check my other answer CAML query that includes folders in result set

Simply changing the operators might get you what you need

<Where>
  <NotIncludes>
    <FieldRef Name='ContentTypeId' />
    <Value Type='ContentTypeId'>0x0120</Value>
  </NotIncludes>
</Where>

I'm not sure if that'll work.

寄与心 2024-07-16 12:06:49

对我来说,它的工作原理如下:-

<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq></Where>

For me also it worked as written below:-

<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq></Where>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文