Social Icons

lunes, 4 de febrero de 2013

Iterando listas Grandes de SharePoint en trozos Pequeños

¿Por qué querría nadie iterar listas de SharePoint por partes? Por dos razones, principalmente. Primero porque si los resultados de una de tus queries son demasiados (por ejemplo 2000) el rendimiento baja mucho al trabajar con ellas y segundo porque quizás solo necesites trabajar con los primeros 20 elementos que cumplan una condición que es demasiado compleja para ser representada en una CAML query.

Yo estoy usand la paginación de queries para hacerlo y es un 75% más rápido que procesar todos los elementos que devuelve la primera query (esto depende también de la cantidad de datos que tengas en la lista)

Básicamente funciona así, pones el RowLimit a un valor prudente (queremos minimizar el número de queries que lanzamos) y luego haces las consultas a SharePoint hasta que el número de resultados llegue al objetivo que nos hemos marcado o te quedes sin elementos en la lita. (Todavía no he probado si es más rápido iterar sobre todos los elementos en una lista grande de golpe o hacerlo por partes pero algo me dice que de esta forma será más rápido)

/// <summary>
/// Returns the top MaxResults items in the query
/// </summary>
internal static List<SPListItem> GetTopItems(SPWeb web, uint MaxResults = 0)
{
    SPList ListToQuery = web.Lists.GetListByInternalName("ListInternalName");


    List<SPListItem> result = new List<SPListItem>();

    SPQuery query = new SPQuery();
    query.Query = string.Format(@"<Where><Eq><FieldRef Name='State' /><Value Type='Choice'>Live</Value></Eq></Where>");
    query.ViewAttributes = "Scope='RecursiveAll'";
    query.RowLimit = MaxResults + 1;

    SPListItemCollection QueryResults;
    string PagingInfo = string.Empty;

    while (result.Count < MaxResults && PagingInfo != null)
    {
        //We set the beginning of the query to the last item in the previous page
        query.ListItemCollectionPosition = new SPListItemCollectionPosition(PagingInfo);

        //We get the page of items
        QueryResults = ListToQuery.GetItems(query);

        foreach (SPListItem item in QueryResults)
        {
            //We process the items and add them to the result list
            if (ComplexProcessing(item))
                result.Add(item);
        }

        //We set PagingInfo to the last item retrieved in the query
        if (QueryResults.ListItemCollectionPosition != null)
            PagingInfo = QueryResults.ListItemCollectionPosition.PagingInfo.ToStringSafe();
        else //PagingInfo will be null if we reach the end of the pagination
            PagingInfo = null;
    }

    return result;
}

Este método de hacer consultas CAML paginadas ha incrementado enormemente el rendimiento de mi sitio, espero que también a ti te sirva.

No hay comentarios: