Consulta CAML na exibição do SharePoint Online

Tenho uma biblioteca muito grande em um ambiente do SharePoint Online:> 3000 (conjuntos de documentos) na pasta raiz e mais de 7000 (conjuntos de documentos, pastas e documentos) no total. O sistema é baseado principalmente em código personalizado: C # CSOM.

Em termos de desempenho, o sistema se beneficiaria muito com a consulta de subconjuntos de todo o conjunto de dados, em vez de todos os 7.000 itens todas as vezes (minha solução atual carrega lotes de 5.000 itens em um ListItemCollection: no meu caso primeiro 5000 e, em seguida, 2000, e a consulta é feita pelo LINQ), especialmente tendo em mente que certas operações estão diretamente ligadas a exibições específicas.

Estou tentando a implementação abaixo, conforme encontrado em um comentário em outro tópico .

Microsoft.SharePoint.Client.List list = ctx.Web.Lists.GetByTitle(ListName); ctx.Load(list); ctx.ExecuteQuery(); Microsoft.SharePoint.Client.View view = list.Views.GetByTitle(viewName); ctx.Load(view); ctx.ExecuteQuery(); CamlQuery query = new CamlQuery(); query.ViewXml = view.ViewQuery; ListItemCollection items = list.GetItems(query); ctx.Load(items); ctx.ExecuteQuery(); 

Meu problema é que ListItemCollection está sendo preenchido com todos os itens da coleção raiz (3000), quando as visualizações escolhidas tentadas consistem em no máximo 60 itens.

A view.ViewQuery é preenchida com este valor:

"<GroupBy Collapse=\"FALSE\" GroupLimit=\"30\"><FieldRef Name=\"CurrentStatus\" /></GroupBy><OrderBy><FieldRef Name=\"CurrentStatus\" Ascending=\"FALSE\" /><FieldRef Name=\"Stage\" /></OrderBy><Where><And><Eq><FieldRef Name=\"Stage\" /><Value Type=\"Text\">Confirm Container</Value></Eq><Eq><FieldRef Name=\"PastTransition\" /><Value Type=\"Boolean\">0</Value></Eq></And></Where>" 

O código acima deveria funcionar? Se sim, o que há de errado? Se não, qual é a outra solução que atinge o mesmo resultado?

Comentários

  • Qual é a aparência do ViewQuery gosta?

Resposta

Você está puxando CAML da visualização porque os usuários podem atualizar os detalhes do filtro? Caso contrário, preparar a consulta manualmente é provavelmente a melhor maneira de proceder.

Experimente:

query.ViewXml ="<View Scope=\"Recursive\"><Query><Where><And><Eq><FieldRef Name=\"Stage\" /><Value Type=\"Text\">Confirm Container</Value></Eq><Eq><FieldRef Name=\"PastTransition\" /><Value Type=\"Boolean\">0</Value></Eq></And></Where></Query></View>" 

Como sua lista tem> 7 mil itens, você também precisa ter certeza de que um ou ambos das colunas Stage e PastTransition são indexadas. Pode depender de qual retorna o subconjunto menor de dados e em que ordem eles são avaliados.

Você também pode precisar fazer “RecursiveAll” ao invés de “Recursive”, dependendo se você deseja / precisa retornar as pastas. Visualize a enumeração do escopo: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx

Isso deve fornecer a lista filtrada. A partir daí, seu código pode fazer qualquer agrupamento / pedido nos itens devolvidos.

Atualizar

Como os detalhes da consulta precisam ser selecionados dinamicamente a partir de visualizações existentes (de acordo com seu feedback abaixo), você pode extrair o conteúdo de fora da visualização existente.ViewQuery e injetá-lo na visualização XML acima. Isso eliminará e também permitirá que a consulta seja executada em listas> 5k.

Veja o código de Jurgen para uma solução completa.

Comentários

  • Funciona assim. Isso significa que configurar uma consulta CAML e filtrar em colunas indexadas com um conjunto de dados consultáveis de mais de 5000 itens não irá travar se o resultado retornado for inferior a 5000? Esta é uma solução alternativa, mas não é realmente uma solução. Não há como obter Eu gostaria de ter a consulta criada dinamicamente a partir de várias visualizações e não ter que recriar a configuração da visualização na consulta CAML cada vez, se isso for possível, é claro. Este é um bom começo já! muito 🙂
  • @JurgenCuschieri: Deve funcionar bem se houver mais de 5K itens de lista. Não tenho certeza se ' estou entendendo totalmente seu caso de uso, mas se quiser extrair os detalhes do filtro da visualização (ou visualizações) dinamicamente, você provavelmente poderá fazer isso copiando a < Consulta > parte da visualização ' s CAML e injetá-lo dinamicamente em < View Scrope = " Recusivo " > < / Exibir >.
  • Eu ' vou tentar isso e reverter para você. Para deixar um pouco mais claro, tenho um sistema em funcionamento com várias consultas diferentes. A consulta CAML é usada para carregar lotes de 5000 itens em uma coleção de itens de lista. LINQ é usado para consultar o ListItemCollection resultante. Desnecessário dizer que a operação leva muito tempo para retornar um resultado. Todo (ou quase todo) cenário é teoricamente vinculado a uma visualização. o que significa que o conjunto de dados consultáveis pode ser minimizado para os mesmos resultados de exibição. portanto, se a consulta caml pode ser preenchida automaticamente a partir da consulta ' s automaticamente – faz mais sentido, não?
  • as visualizações definem estágios específicos dentro de uma empresa cliente ' s processo de negócios. aquelas operações de consulta CAML que são usadas especificamente dentro de um estágio, podem, portanto, usar a mesma consulta que a visualização. Isso irá refinar o conjunto de dados consultáveis, em vez de usar todos os itens da lista todas as vezes
  • Ótimo! Ainda bem que deu certo. Nós, desenvolvedores do SharePoint, temos que ficar juntos … 🙂

Resposta

A seguir está minha solução final, com base na resposta de @Jim Barntish “.

Microsoft.SharePoint.Client.List list = ctx.Web.Lists.GetByTitle(ListName); ctx.Load(list); ctx.ExecuteQuery(); Microsoft.SharePoint.Client.View view = list.Views.GetByTitle(viewName); ctx.Load(view); ctx.ExecuteQuery(); CamlQuery query = new CamlQuery(); query.ViewXml = view.ViewQuery; int pFrom = query.ViewXml.IndexOf("<Where>") + "<Where>".Length; int pTo = query.ViewXml.LastIndexOf("</Where>"); string whereClause = query.ViewXml.Substring(pFrom, pTo - pFrom); string queryStr = "<View Scope=\"Recursive\"><Query><Where>" + whereClause + "</Where></Query></View>"; query.ViewXml = queryStr; ListItemCollection items = list.GetItems(query); ctx.Load(items); ctx.ExecuteQuery(); 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *