2008-12-02 8 views
21

Ich benutze die caml-Abfrage, um alle Dokumente auszuwählen, die vom Benutzer geändert oder hinzugefügt wurden. Abfrage wird rekursiv für alle Unterwebsites der angegebenen Websitesammlung ausgeführt.CAML-Abfragen: Wie filtert man Ordner aus der Ergebnismenge?

Jetzt Problem ist, ich kann Ordner nicht loswerden, die auch Teil der Ergebnismenge sind. Für den Moment filtere ich sie aus Ergebnis Datentabelle. Aber ich frage mich: Ist es möglich, Ordner aus der Ergebnismenge herauszufiltern, indem nur caml verwendet wird?

Antwort

22

diese CAML macht tatsächlich den Trick:

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

, die Ihnen keine Ordner geben wird.

+0

Versucht dies, hat aber nicht funktioniert. Nur Ordner anzeigen - keine Daten. – JohnnyBizzle

+0

I meine Suche nach einer Nur-Ordner-Abfrage kam ich zu diesem Thema. Diese CAML-Abfrage funktioniert tatsächlich für mich auf SharePoint 2013. Ich habe den Int in natürlich geändert, aber 0 funktioniert großartig, wenn Sie nur Dateien möchten. – Martin

+2

Dies funktioniert aus CSOM 0

12

Also, ich habe es herausgefunden :) Sie können FieldRef = 'ContentType' in Ihrer Caml-Abfrage verwenden und Typ des Inhaltstyps angeben, den Sie auswählen oder von der Auswahl ausschließen möchten.

Also in meinem Fall habe ich diesen Zustand zu meinem caml Ausdruck hinzugefügt:

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

HINWEIS: Es gibt Probleme in Multi-Language-Setup. Name des Inhaltstypen kann unterschiedlich sein, so ist es gut Namen von Inhaltstypen von Ressourcen

UPDATE zu erhalten:

Es sieht aus wie ich in meinen Annahmen zu schnell war. Ich muss alle Contatt-Typen basierend auf Ordner Inhaltstyp filtern, weil in unseren Projekten solche Inhaltstypen verwendet werden :(

Ich konnte keine ausführbare Abfrage in Caml erstellen, also fügte ich View-Feldelement zu meiner Abfrage welche wählt ContentTypeId von Listenelement und I-Filter-out Zeilen, die auf Ordnerinhaltstyp basieren.

-Code ist dies trivial zu tun, aber es stört mich, dass eine solche einfache Aufgabe nicht durch reine caml getan werden kann.

+4

Ich habe Ihre Antwort abgelehnt, weil die Antwort von Johan Leino auf SharePoint 2013 funktioniert. Das sollte jetzt die akzeptierte Antwort sein. – Martin

+0

Ich habe dies aufgestuft, weil der REST-Aufruf aus irgendeinem seltsamen Grund für '$ filter = FSObjType eq 0 'fehlschlägt. ContentTypeId funktioniert, sieht aber wie ein Hack aus. – nawfal

+0

Einige Informationen hier: http://sharepoint.stackexchange.com/questions/124846/rest-with-filter-for-list-items-in-sharepoint-2013 – nawfal

3

Wenn Sie mit Ordnern arbeiten und ein SPQuery-Objekt verwenden, können Sie auch das Feld ViewAttributes verwenden, um den rekursiven Objektabruf zu ermöglichen. Wenn Sie den Wert auf Scope = "Recursive" festlegen, werden Elemente aus Unterordnern abgerufen und die Ordnerobjekte in der Ergebnismenge nicht abgerufen.

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

Dies ist, was für mich meine anderen arbeitete

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

Versuchte dies, hat aber nicht funktioniert. Nur Ordner anzeigen - keine Daten. – JohnnyBizzle

0

prüfen Antwort CAML query that includes folders in result set

einfach die Betreiber zu ändern können Sie bekommen, was Sie brauchen

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

Ich bin nicht sicher, ob das funktioniert.

4

Nach der Ausgabe von CAML Designer (erstellt von Karine Bosch und Andy Van Steenbergen und vertrieben von dem Belux Information Worker User Group) die richtige CAML Syntax:

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

Getestet habe ich diese in Powershell und bekam die erwartetes Ergebnis:

$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 

können Sie den <QueryOptions>-Tag in der CAML mit der Objekteigenschaft ViewAttributes SPQuery ersetzen, wenn Sie es vorziehen, das heißen $qry.ViewAttributes = “Scope=’RecursiveAll’".

Achten Sie beim Testen darauf, das SPQuery-Objekt jedes Mal neu zu instanziieren, da Sie die Query-Eigenschaft nicht einfach neu zuweisen können. Sobald die Abfrage ausgeführt wurde, wird jeder neue Wert, der der Query-Eigenschaft zugewiesen ist, ignoriert. Führen Sie das gesamte PowerShell-Fragment aus.

0

Für mich auch arbeitete er als unten geschrieben: -

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

1 Atul

1

Dave T.'s answer nicht für mich arbeiten, aber es als Inspiration nehmen hier ist, was ich kam mit:

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

Der Haupt Problem ist, dass wir nur ContentTypeId auf einer Site-Ebene wissen können, denn wenn ein Inhaltstyp zu einer Liste/Bibliothek hinzugefügt wird, wird ein Listeninhaltstyp und seine ID ist a pendelte mit einer anderen GUID (0x010100 ...). Und es gibt keine NotBeginsWith Bedingung in CAML, so können wir Ordner nicht ausfiltern, aber wir können Dokumente nur, die Site-Inhaltstyp-ID ist 0x0101.

Die Lösungen mit FSObjType Feld für mich nicht arbeiten, weil ich Bibliotheken mit weit mehr Dateien als eine Schwelle haben, so dass alle Felder in der Abfrage indiziert werden müssen, und ich habe einen Weg zu indizieren dieses Feld nicht gefunden .