2008-12-02 72 views
21

我正在使用caml查询来选择用户修改或添加的所有文档。查询在指定网站集的所有子网站上递归运行。CAML查询:如何从结果集中筛选文件夹?

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

回答

22

这CAML其实也有诀窍:

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

这将不会给你任何文件夹。

+0

试过这个,但没有奏效。只显示文件夹 - 没有数据。 – JohnnyBizzle 2010-12-16 17:43:58

12

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

所以在我的情况我已经添加了这个条件,我的CAML表达:

<Neq><FieldRef Name='ContentType' /><Value Type='Text'>文件夹</Value></Neq>

注: 有在多国语言设置问题。内容类型的名称可以是不同的,所以这是好事,从资源获取

内容类型的名称

UPDATE:

它看起来像我是在我的假设太快。我需要根据文件夹内容类型过滤出所有类型的作品,因为在我们的项目中使用了以下内容类型:(

我无法在caml中创建可行的查询,因此我将查看字段元素添加到了我的查询中选择是基于文件夹的内容类型和我的列表项的ContentTypeId筛选出的行。

代码做,这是小事,但它困扰我,这种简单的任务不能纯CAML来完成。

+4

由于Johan Leino的答案适用于SharePoint 2013,因此我低估了您的答案。这应该是现在已被接受的答案。 – Martin 2015-01-07 08:27:25

+0

我提高了这一点,因为由于某种奇怪的原因,REST调用失败了'$ filter = FSObjType eq 0`。 ContentTypeId的作品,虽然看起来像一个黑客。 – nawfal 2016-02-04 19:53:10

+0

一些信息在这里:http://sharepoint.stackexchange.com/questions/124846/rest-with-filter-for-list-items-in-sharepoint-2013 – nawfal 2016-02-05 06:39:30

3

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

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

这是为我工作

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

检查我的其他答案CAML query that includes folders in result set

简单地改变运营商可能会得到你所需要的

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

我不是当然,如果那会工作。

4

CAML Designer输出(通过卡林纳博世和安迪·范·斯滕贝亨创建和分发由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 

,如果你愿意的话,也就是$qry.ViewAttributes = “Scope=’RecursiveAll’"您可以替换与SPQuery对象属性ViewAttributes的CAML的<QueryOptions>标签。

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

0

对我来说也是它的工作是写如下: -

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

Dave T.'s answer我没有工作,但以它为这里的灵感是我想出了:

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

主要问题在于我们只能知道ContentTypeId在网站级别上,因为当内容类型被添加到列表/库时,它将成为列表内容类型,其ID是使用另一个GUID(0x010100 ...)进行填充。并且在CAML中有no NotBeginsWith条件,所以我们不能过滤出文件夹,但我们可以包含文档哪些网站内容类型ID是0x0101

FSObjType领域的解决方案不适合我,因为我有大于阈值远远更多的文件库,以便查询中的所有字段必须被索引,我还没有找到一种方法来索引这个领域。