Подтвердить что ты не робот

CAML-запросы: как фильтровать папки из набора результатов?

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

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

4b9b3361

Ответ 1

Эта CAML на самом деле делает трюк:

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

который не даст вам никаких папок.

Ответ 2

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

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

<Neq > <FieldRef Name='ContentType'/" > <Value Type='Text' > Папка </Value > </Neq >

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

UPDATE:

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

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

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

Ответ 3

В соответствии с результатом 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

Вы можете заменить тег <QueryOptions> в CAML на свойство объекта SPQuery ViewAttributes, если хотите, т.е. $qry.ViewAttributes = "Scope=’RecursiveAll’".

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

Ответ 4

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

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

Ответ 5

Dave T. answer не сработал у меня, но в качестве вдохновения здесь я придумал:

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

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

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

Ответ 6

Это то, что сработало для меня

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

Ответ 7

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

Простое изменение операторы могут получить то, что вам нужно

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

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

Ответ 8

Для меня это также сработало следующим образом: -

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