web-dev-qa-db-ja.com

CAMLクエリ:結果セットからフォルダーをフィルターする方法?

Camlクエリを使用して、ユーザーが変更または追加したすべてのドキュメントを選択しています。クエリは、指定されたサイトコレクションのすべてのサブサイトで再帰的に実行されます。

今問題は、結果セットの一部でもあるフォルダーを削除できないことです。今のところ、結果データテーブルからそれらをフィルタリングしています。しかし、私は疑問に思っています:camlを使用するだけで結果セットからフォルダーをフィルターで除外することは可能ですか?

21
drax

このCAMLは実際にトリックを実行します。

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

それはあなたにフォルダを与えません。

25
Johan Leino

したがって、私はそれを理解しました:) camlクエリでFieldRef = 'ContentType'を使用して、選択または選択から除外するコンテンツタイプのtyprを指定できます。

したがって、私の場合、この条件をcaml式に追加しました。

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

注:多言語設定に問題があります。コンテンツタイプの名前は異なる場合があるため、リソースからコンテンツタイプの名前を取得することをお勧めします

更新:

想定が速すぎたようです。私たちのプロジェクトではそのようなコンテンツタイプが使用されているため、フォルダコンテンツタイプに基づいてすべてのcontettタイプを除外する必要があります:(

Camlで実行可能なクエリを作成できなかったため、リスト項目のContentTypeIdを選択するビューフィールド要素をクエリに追加し、フォルダーのコンテンツタイプに基づく行をフィルターで除外しました。

これを行うためのコードは簡単ですが、そのような単純なタスクを純粋なcamlで実行することはできません。

13
drax

CAML Designer (Karine BoschとAndy Van Steenbergenが作成し、Belux Information Worker User Groupが配布)の出力によると、正しい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

<QueryOptions>必要に応じて、SPAMLオブジェクトプロパティViewAttributesを含むCAMLのタグ、つまり$qry.ViewAttributes = “Scope=’RecursiveAll’"

Queryプロパティを単純に再割り当てすることはできないため、これをテストするときは、必ずSPQueryオブジェクトを必ず再インスタンス化してください。クエリが実行されると、Queryプロパティに割り当てられた新しい値はすべて無視されます。したがって、PowerShellフラグメント全体を実行します。

5
JohnC

フォルダーを使用していて、SPQueryオブジェクトを使用している場合は、ViewAttributesフィールドを使用して再帰的なアイテムの取得を許可することもできます。値をScope = "Recursive"に設定すると、サブフォルダーからアイテムが取得され、結果セット内のフォルダーオブジェクトは取得されません。

myQuery.ViewAttributes = "Scope=\"Recursive\"";
5
Peter Jacoby

Dave T.の答え はうまくいきませんでしたが、それをインスピレーションとして、ここに私が思いついたものがあります。

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

主な問題は、コンテンツタイプがリスト/ライブラリに追加されるとリストコンテンツタイプとそのIDになるため、サイトレベルのContentTypeIdしか認識できないことです。別のGUID(0x010100 ...)が追加されます。そしてCAMLにno NotBeginsWith条件があるため、フォルダーをフィルターで除外することはできませんが、含めることはできます- ドキュメントのみどのサイトコンテンツタイプIDかx0101

FSObjTypeフィールドのソリューションは、しきい値よりもはるかに多くのファイルを含むライブラリがあるため、クエリですべてのフィールドにインデックスを付ける必要があり、これにインデックスを付ける方法が見つからないため、機能しませんフィールド。

2
Rustam

これは私のために働いたものです

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

私の他の答えを確認してください 結果セットにフォルダーを含むCAMLクエリ

演算子を変更するだけで、必要なものが得られる場合があります

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

それがうまくいくかどうかはわかりません。

0
Dave T.

私にとっても以下のように機能しました:-

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