CAML-запросы: как отфильтровать папки из набора результатов? - PullRequest
21 голосов
/ 02 декабря 2008

Я использую запрос caml, чтобы выбрать все документы, которые были изменены или добавлены пользователем. Запрос выполняется рекурсивно на всех дочерних сайтах указанного семейства сайтов.

Теперь проблема в том, что я не могу избавиться от папок, которые также являются частью набора результатов. Пока я отфильтровываю их по результатам. Но мне интересно: возможно ли отфильтровать папки из результирующего набора, используя caml?

Ответы [ 8 ]

24 голосов
/ 03 сентября 2009

Этот CAML на самом деле делает свое дело:

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

, что не даст вам никаких папок.

12 голосов
/ 02 декабря 2008

Итак, я понял это :) Вы можете использовать FieldRef = 'ContentType' в своем запросе caml и указать typr типа контента, который вы хотите выбрать или исключить из выбора.

Так что в моем случае я добавил это условие к своему выражению caml:

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

Примечание: Есть проблемы в многоязычной настройке. Название типа контента может быть разным, поэтому полезно получать имена типов контента из ресурсов

UPDATE:

Похоже, я был слишком быстр в своих предположениях. Мне нужно отфильтровать все типы контекстов на основе типа содержимого папки, потому что в наших проектах используются такие типы содержимого: (

Мне не удалось создать работоспособный запрос в caml, поэтому я добавил в свой запрос элемент поля просмотра, который выбирает ContentTypeId элемента списка, и я отфильтровываю строки, основанные на типе содержимого папки.

Код для этого тривиален, но меня беспокоит, что такое простое задание не может быть выполнено чистым caml.

5 голосов
/ 14 мая 2013

В соответствии с выводом CAML Designer (созданным Карин Бош и Энди Ван Стеенбергеном и распространяемым группой пользователей Belux Information Worker) правильный синтаксис 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> в CAML на свойство объекта SPQuery ViewAttributes, если хотите, например, $qry.ViewAttributes = “Scope=’RecursiveAll’".

При тестировании обязательно повторяйте экземпляр объекта SPQuery каждый раз, так как вы не можете просто переназначить свойство Query. После выполнения запроса любое новое значение, присвоенное свойству Query, игнорируется. Итак, выполните весь фрагмент PowerShell.

5 голосов
/ 22 апреля 2010

Если вы работаете с папками и используете объект SPQuery, вы также можете использовать поле ViewAttributes, чтобы разрешить рекурсивный поиск элементов. Установка значения Scope = "Recursive" будет извлекать элементы из подпапок и не будет извлекать объекты папки в наборе результатов.

myQuery.ViewAttributes = "Scope=\"Recursive\"";
2 голосов
/ 01 декабря 2016

Ответ Дейва Т. не сработал для меня, но воспринял это как вдохновение вот что я придумал:

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

Основная проблема в том, что мы можем знать только ContentTypeId на уровне сайта , потому что, когда тип контента добавляется в список / библиотеку, он становится типом контента списка и его К идентификатору добавляется другой GUID (0x010100 ...). И в CAML нет условия NotBeginsWith , поэтому мы не можем отфильтровать папки, но мы можем включать только документы с идентификатором типа контента сайта 0x0101 .

Решения с полем FSObjType не работают для меня, потому что у меня есть библиотеки с гораздо большим количеством файлов, чем порог, поэтому все поля в запросе должны быть проиндексированы, и я не нашел способа индексировать это поле.

0 голосов
/ 09 февраля 2016

Для меня это также работает как написано ниже: -

<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq></Where>
0 голосов
/ 22 декабря 2011

Проверьте мой другой ответ CAML-запрос, содержащий папки в наборе результатов

Простая смена операторов может дать вам то, что вам нужно

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

Я не уверен, что это сработает.

0 голосов
/ 30 июля 2010

Вот что у меня сработало

   <Where>
      <Eq>
         <FieldRef Name='FSObjType' />
         <Value Type='Number'>1</Value>
      </Eq>
   </Where>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...