Pergunta

Então, estou construindo uma webpart que enumera todos os doclibs na web atual, pegando todos os arquivos com check-out e listando-os em uma tabela, permitindo que um usuário aplique alguns metadados necessários e faça check-in de muitos de uma vez (50).

Esta webpart deve operar em listas acima do limite de exibição de lista (atualmente definido em 15.000 em produção) e também em sites MUITO grandes (50.000 a 100.000+ documentos).

Estou seguindo as práticas recomendadas da MS para lidar com listas grandes aqui: http://msdn.microsoft.com/en-us/library/ee557257.aspx

Usando uma SPquery (sem nenhum CAML definido), recuperando páginas de 2.000 itens e analisando dessa forma.O problema com isso é que a webpart está, na verdade, causando um tempo limite nesses sites muito grandes (50k+).Então, estou tentando ser um pouco mais inteligente com meu CAML, obtendo apenas itens que estão em check-out:

spQuery.Query = "<Where><IsNotNull>
    <FieldRef Name=\"CheckoutUser\" LookupId=\"TRUE\"/>
</IsNotNull></Where>";
spQuery.RowLimit = 2000;
spQuery.ViewAttributes = "Scope=\"Recursive\"";

Estou usando um CrossListQueryInfo query para consultar toda a web com esse mesmo caml, e funciona maravilhosamente bem quando nenhuma lista está no LVT.Se for, capturo essa exceção e tento novamente com o SPQuery 'mais lento' em cada biblioteca individual.

De tudo que estou lendo, desde que meu CAML retorne menos itens que o LVT, ele deve funcionar.Mas usar o CAML acima causa o erro The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator para ser jogado quando SPList.GetItems(spQuery) é chamado.Como estou definindo um limite de 2.000 linhas, isso não deveria acontecer?MS sugere executar um SPQuery sem nenhum CAML definido - basicamente pegando todos os itens da biblioteca em páginas de 2.000.Portanto, não consigo entender por que meu CAML está falhando apenas em listas acima do limite de visualização.

Editar:Após mais pesquisas, estou tentando utilizar o ContentIterator classe para atender às minhas necessidades (http://msdn.microsoft.com/en-us/library/microsoft.office.server.utilities.contentiterator.aspx).Usando exemplos desta postagem: http://extreme-sharepoint.com/2012/07/17/data-access-via-caml-queries/

Ainda estou falhando no contentiterador com o mesmo erro de LVT.

O campo 'CheckoutUser' precisa ser indexado em todas as listas nas quais queremos executar esta consulta?

Atualização 2:Isso se resume ao fato de o campo 'CheckoutUser' não estar indexado e tentar consultá-lo.Infelizmente, não é uma opção forçarmos esse índice em todas as bibliotecas da fazenda.Acredito que minha única opção neste momento é implementar algum tipo de esquema de paginação em sites muito grandes para processar itens em lotes.

Atualização final:Como solução, decidi impor a indexação da coluna 'CheckoutUser' para bibliotecas.Isto deve melhorar enormemente o desempenho geral da webpart e permitir suporte para sites muito grandes.Haverá um pouco de dor de cabeça imediatamente após a implantação, pois precisaremos definir manualmente o índice da coluna nas listas acima do limite de exibição de lista, mas no longo prazo isso será melhor.

Foi útil?

Solução

Minha compreensão de como o limite de exibição de lista funciona é limitada, no entanto, suspeito que o motivo pelo qual sua consulta CAML está falhando é porque ela está filtrando no campo não indexado e o RowLimit é aplicado "depois".

Acho que indexar o campo CheckoutUser resolveria seu problema, porém parece que você tem muitos sites.

Permita-me sugerir uma abordagem alternativa – paginação.Como a coluna ID em cada lista é indexada, implemente uma consulta CAML onde você está filtrando PRIMEIRO (muito importante) na coluna ID menor que, digamos, 2.000 e, em segundo lugar, no campo CheckoutUser.Se essa consulta não retornar o número desejado de resultados, aumente de 2.000 para 4.000 e repita.

Eu não implementei esta solução sozinho, é apenas uma ideia.

Outras dicas

Se você estiver consultando listas grandes, definitivamente deverá indexar os campos nos quais está consultando.A limitação não ocorre porque os campos indexados são armazenados em uma tabela separada no banco de dados.

Esta minha postagem no blog deve ser de alguma ajuda, eu acho:http://vrdmn.blogspot.in/2012/11/sharepoint-list-indexes-under-hood.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top