Codepoint

by Trentia Consulting

SharePoint 2013 : Evitando el error ‘The Maximum allowed value is 4096’

Recientemente trabajando en el desarrollo de una aplicación web con base de SharePoint 2013, se me ordenó el desarrollo de un centro de búsqueda y de descarga de contenidos en SharePoint, así que me puse manos a la obra.

Esta parte de la aplicación permite al usuario recibir gran cantidad de contenidos por lo que decidimos atacar al servicio de búsqueda de SharePoint 2013 utilizando la librería CSOM 15, dado que las búsquedas sería mucho más optimas y mejoraría la experiencia de usuario. Así mismo existen gran cantidad de filtros que permite al usuario realizar una criba muy especifica de los contenidos que desea recibir. En este proceso se construye una consulta en Keyword Query Languaje (KQL en adelante) dependiendo de los datos que el usuario haya seleccionado en la sección de filtros.

Así pues el código que genera la consulta tiene un aspecto similar a este :

/// <summary>
/// Searches al documents that maches the specified metadata and retrieve all specified properties
/// </summary>
/// <param name="Filters">Filters to add</param>
/// <param name="PropertiesName">Properties to retrieve</param>
/// <returns></returns>
public IEnumerable<IDictionary<string, object>> SearchDocuments(IDictionary<string, object> Filters, IEnumerable<string> PropertiesName)
{
    using (var context = new ClientContext(_host))
    {

        context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
        context.FormsAuthenticationLoginInfo = new FormsAuthenticationLoginInfo(_user, _password);

        KeywordQuery query = new KeywordQuery(context);
        if(PropertiesName != null)
        {
            foreach (var PropertyName in PropertiesName)
            {
                query.SelectProperties.Add(PropertyName);
            }
        }

        query.QueryText = "IsDocument=true";

        if (Filters != null && Filters.Any())
            query.QueryText = query.QueryText + " AND ";

        foreach (var filter in Filters)
        {
            if (filter.Value is Array)
            {
                query.QueryText = query.QueryText + "( ";
                foreach (var valueItem in filter.Value as IEnumerable<object>)
                {
                    query.QueryText = query.QueryText + filter.Key + ":*" + valueItem.ToString() + "*";
                    if (((IEnumerable<object>)filter.Value).Last() != valueItem)
                        query.QueryText = query.QueryText + " OR ";
                    else
                        query.QueryText = query.QueryText + " ) ";
                }
            }
            else
            {
                if (filter.Value is bool)
                {
                    query.QueryText = query.QueryText + filter.Key + "=" + filter.Value.ToString().ToLower();
                }
                else
                {
                    query.QueryText = query.QueryText + filter.Key + ":*" + filter.Value.ToString() + "*";
                }
            }
            if (Filters.Last().Key != filter.Key)
                query.QueryText = query.QueryText + " AND ";
        }

        SearchExecutor executor = new SearchExecutor(context);
        ClientResult<ResultTableCollection> results = executor.ExecuteQuery(query);

        context.ExecuteQuery();
        return results.Value[0].ResultRows;
    }
}

 

Habiendo visto el código que genera las consultas, es fácil imaginar que es posible que la consulta KQL alcance grandes tamaños sobretodo si añadimos que muchos de los valores que se usan en la búsqueda son identificadores globales únicos (GUID por sus siglas en inglés).

Si construimos pues, una consulta excesivamente larga y la lanzamos contra el servicio de búsqueda de SharePoint 2013, recibiremos esta excepción : ( y ningún resultado )

System.ArgumentOutOfRangeException : The Maximum allowed value is 4096, Parameter Name ‘QueryText’

   ¿Por que es lanzada esta excepción ? SharePoint 2013 tiene un limite de caracteres en la búsqueda cuando se usa KQL, este por defecto está establecido en 4096 bytes lo que no permite realizar consultas muy largas o muy complejas. Pero esto tiene solución o por lo menos para la mayoría de los casos, pues este límite se puede incrementar. lo que en la mayoría de casos nos permitirá realizar las consultas que antes no nos permitía el límite de caracteres.

¿ Por que digo que se puede solucionar para la mayoría de los casos ? Pues por que el límite “sólo” se puede incrementar hasta 20480 bytes, lo que en la mayoría de casos nos permitirá realizar las consultas que antes no nos permitía el límite de caracteres. Esta tarea es sencilla pero no se puede realizar desde la administración central de SharePoint 2013 si no que tendremos que establecer el nuevo valor desde la “SharePoint 2013 Management Shell”. El valor que tenemos que modificar es una propiedad llamada MaxKeywordQueryTextLength del servicio de búsqueda. Para realizar eso abriremos como administradores una “SharePoint 2013 Management Shell” e introduciremos los siguientes comandos en la consola :

PS C:\Users\trentia> $search = Get-SPServiceApplication | where {$_.displayname -contains "search"}
PS C:\Users\trentia> $search.MaxKeywordQueryTextLength
4096
PS C:\Users\trentia> $search.MaxKeywordQueryTextLength = 20480
PS C:\Users\trentia> $search.Update()
PS C:\Users\trentia> $search.MaxKeywordQueryTextLength
20480
## Quizás no sea necesario pero cerciorémonos que todo quede intacto
 
PS C:\Users\trentia> Restart-Service spsearchhostcontroller
PS C:\Users\trentia> IISRESET

Y con este sencillo proceso el límite queda incrementado hasta 20 kb lo que nos permitirá realizar consultas muchísimo más complejas.

Espero que sea de ayuda !

Agregar comentario

Loading