sharepoint - operator - caml query builder
Consultas CAML: ¿cómo filtrar las carpetas del conjunto de resultados? (8)
Estoy usando la consulta de Caml para seleccionar todos los documentos que fueron modificados o agregados por el usuario. Query se ejecuta de forma recursiva en todos los subsitios de la colección de sitios especificada.
Ahora el problema es que no puedo deshacerme de las carpetas que también forman parte del conjunto de resultados. Por ahora los estoy filtrando de la tabla de datos de resultados. Pero me pregunto: ¿es posible filtrar las carpetas del conjunto de resultados simplemente usando caml?
Compruebe mi otra respuesta CAML consulta que incluye carpetas en conjunto de resultados
Simplemente cambiando los operadores puede obtener lo que necesita
<Where>
<NotIncludes>
<FieldRef Name=''ContentTypeId'' />
<Value Type=''ContentTypeId''>0x0120</Value>
</NotIncludes>
</Where>
No estoy seguro si eso funcionará.
De acuerdo con el resultado de CAML Designer (creado por Karine Bosch y Andy Van Steenbergen y distribuido por Belux Information Worker User Group), la sintaxis correcta de CAML es:
<Where>
<Eq>
<FieldRef Name=''FSObjType'' />
<Value Type=''Integer''>0</Value>
</Eq>
</Where>
<QueryOptions>
<ViewAttributes Scope=''RecursiveAll'' />
</QueryOptions>
Probé esto en PowerShell y obtuve el resultado esperado:
$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
Puede reemplazar la etiqueta <QueryOptions>
en el CAML con la propiedad de objeto SPQuery ViewAttributes si lo prefiere, es decir, $qry.ViewAttributes = “Scope=''RecursiveAll''"
.
Al probar esto, asegúrese de volver a crear una instancia del objeto SPQuery cada vez, ya que no puede reasignar la propiedad Query. Una vez que se ha ejecutado la consulta, se ignora cualquier valor nuevo asignado a la propiedad Query. Así que ejecuta todo el fragmento de PowerShell.
Entonces, lo descubrí :) Puedes usar FieldRef = ''ContentType'' en tu consulta de cámara y especificar el tipo de contenido que deseas seleccionar o excluir de la selección.
Entonces, en mi caso, he agregado esta condición a mi expresión caml:
<Neq
> <FieldRef Name=''ContentType''
/> <Value Type=''Text''
> Carpeta </Value
> </Neq
>
NOTA: hay problemas en la configuración de varios idiomas. El nombre del tipo de contenido puede ser diferente, por lo que es bueno obtener los nombres de los tipos de contenido de los recursos
ACTUALIZAR:
Parece que fui demasiado rápido en mis suposiciones. Necesito filtrar todos los tipos contett basados en el tipo de contenido de la carpeta, porque en nuestros proyectos se usan tales tipos de contenido :(
No pude crear una consulta viable en caml, así que agregué el elemento de campo de vista a mi consulta, que selecciona ContentTypeId del elemento de la lista y las filas de filtrado que se basan en el tipo de contenido de la carpeta.
El código para hacer esto es trivial, pero me molesta que una tarea tan simple no se pueda hacer por puro caml.
Este CAML realmente hace el truco:
<Where>
<Eq>
<FieldRef Name=''FSObjType'' />
<Value Type=''Integer''>0</Value>
</Eq>
</Where>
eso no te dará ninguna carpeta.
Esto es lo que funcionó para mí
<Where>
<Eq>
<FieldRef Name=''FSObjType'' />
<Value Type=''Number''>1</Value>
</Eq>
</Where>
Para mí también funcionó como se describe a continuación:
<Where><Eq><FieldRef Name=''FSObjType'' /><Value Type=''Integer''>1</Value></Eq></Where>
Si está trabajando con carpetas y está utilizando un objeto SPQuery, también puede utilizar el campo ViewAttributes para permitir la recuperación recursiva de elementos. Establecer el valor en Scope = "Recursive" recuperará los elementos de las subcarpetas y no recuperará los objetos de la carpeta en el conjunto de resultados.
myQuery.ViewAttributes = "Scope=/"Recursive/"";
La respuesta de Dave T. no funcionó para mí, pero tomarlo como inspiración es lo que se me ocurrió:
<Where>
<BeginsWith><FieldRef Name="ContentTypeId" />
<Value Type="ContentTypeId">0x0101</Value>
</BeginsWith>
</Where>
El principal problema es que solo podemos conocer ContentTypeId en un nivel de sitio , porque cuando un tipo de contenido se agrega a una lista / biblioteca se convierte en un tipo de contenido de lista y su ID se agrega con otro GUID (0x010100 ...). Y no hay ninguna condición NotBeginsWith en CAML, por lo que no podemos filtrar las carpetas, pero podemos incluir solo los documentos cuyo tipo de identificación del sitio sea 0x0101 .
Las soluciones con el campo FSObjType no me funcionan porque tengo bibliotecas con muchos más archivos que un umbral, por lo que todos los campos de la consulta deben indexarse y no he encontrado una forma de indexar este campo.