Primeros pasos con Azure Search: Los índices

Muy buenas a todos.

Hoy, quiero empezar a hablar sobre un servicio al que tenía muchas ganas de dedicarle un tiempo, el servicio Azure Search. A lo largo de los próximos días haremos un overview completo sobre este servicio y veremos cómo funciona y qué podemos hacer con él.

El servicio Azure Search permite añadir una robusta experiencia de búsqueda a nuestras aplicaciones usando una API REST o una SDK .NET sin gestionar la infraestructura de búsqueda o llegar a ser un experto en búsqueda.

En el siguiente enlace, podréis ver una descripción más profunda sobre este servicio:

https://azure.microsoft.com/en-us/documentation/articles/search-what-is-azure-search/

En el post de hoy, vamos a  ver cómo configurar el servicio de búsqueda y el primer paso a la hora de poder comenzar a trabajar con el mismo, los índices.

Configurando el servicio de búsqueda en Azure

Lo primero que debemos hacer es aprovisionar el servicio de búsqueda. Para ello, en el nuevo portal de Azure, iremos a Nuevo->Datos y almacenamiento->Búsqueda de Azure, como se ve en la siguiente imagen.

Captura de pantalla 2016-01-16 a las 16.08.41

A continuación, tenemos que indicar los datos básicos de configuración del servicio: el nombre del servicio, el grupo de recursos al que pertenece, la ubicación y el nivel de precios.

Captura de pantalla 2016-01-16 a las 16.11.14

Para este servicio disponemos de dos niveles de precios, con diferentes características que harán que en función de la finalidad del uso del servicio, elijamos uno u otro.

Captura de pantalla 2016-01-18 a las 23.27.48

Una vez configurados todos los parámetros, pulsamos sobre crear y el servicio se aprovisionará, con lo que ya lo tendremos listo para usar.

Los índices en Azure Search

Un índice es el medio principal para organizar y buscar documentos en el servicio de búsqueda de Azure, similar a cómo se organizan los registros en una tabla de una base de datos. Cada índice tiene una colección de documentos que cumplen el esquema de índice (nombres de campo, tipos de datos y propiedades), pero los índices también especifican construcciones adicionales (proveedores de sugerencias, perfiles de puntuación y configuración de CORS) que definen otros comportamientos de la búsqueda.

Por tanto es necesario, como paso previo a subir documentos al servicio de búsqueda, definir un índice y su estructura, que no es más que una estructura de tablas que acepta datos y consultas. Los índices en el servicio de búsqueda de Azure, se pueden crear de tres formas, o desde el propio portal de Azure o por medio de código usando una SDK de .NET o una API REST.

A continuación, vamos a ver como crear un índice por medio de la SDK y la API REST en un solución de consola de Visual Studio.

Creando índices en Azure Search

Para ello, vamos a crear una aplicación de consola en Visual Studio. Una vez creada, tenemos que añadir las referencias a la SDK de Azure Search. Esto lo conseguiremos ejecutando en la consola de Nuget el siguiente comando:

Install-Package Microsoft.Azure.Search -Pre

Nos instalará todas las referencias necesarias para poder trabajar con la SDK correspondientes. Además, para el resto del ejemplo necesitaremos añadir otras dos referencias:

System.Configuration (Con la que tendremos la posibilidad de hacer referencia al App.Config de nuestra aplicación)

System.Net (Necesaria para poder llamadas REST desde la aplicación de consola).

Una vez añadidas todas las referencias, podemos pasar a ver el código. Para la aplicación de consola hemos creado un sencillo menú que nos permite elegir entre las dos opciones que tiene nuestra aplicación, crear un índice usando la SDK, o crear un índice por medio de API REST. Este es el código que implementa el menú:


class Program
 {
 static void Main(string[] args)
 {
 int option;

do
 {
 option = menu();
 switch (option)
 {
 case 1:

SearchServiceClient serviceClient = GetSearchServiceClient();

DeleteIndexIfExists(serviceClient,"files");
 CreateIndexUsingNetSDK(serviceClient,"files");

Console.WriteLine("Index successfully created");

break;
 case 2:

SearchServiceClient serviceClient2 = GetSearchServiceClient();

DeleteIndexIfExists(serviceClient2,"files");

CreateIndexUsingRESTAPI("files");

break;
 default:
 break;
 }
 }
 while (option != 0);
 }

private static int menu()

 {
 int value = 0;

Console.WriteLine("-----------------------------------");
 Console.WriteLine("1.- Create an index using .NET SDK");
 Console.WriteLine("2.- Create an index using REST API");
 Console.WriteLine("0.- Exit");
 Console.WriteLine("-----------------------------------");

do
 {
 Console.WriteLine("Enter an valid option: ");
 value = Int16.Parse(Console.ReadLine());
 }
 while (value < 0 && value > 2);

return value;
 }

}

Como veréis, este código hace referencia a cuatro funciones, que son la clave de este post y que son en las que nos vamos a centrar para describir a continuación.

GetSearchServiceClient: Esta función nos va a devolver un objeto de tipo SearchServiceClient que es el que nos permite interaccionar con el servicio de búsqueda.

private static SearchServiceClient GetSearchServiceClient()
{
string serviceName = ConfigurationManager.AppSettings["SearchServiceName"];
string apiKey = ConfigurationManager.AppSettings["ApiKey"];

SearchServiceClient serviceClient = new SearchServiceClient(serviceName, new SearchCredentials(apiKey));

return serviceClient;
}

Este método solo se encarga de crear un nuevo objeto de tipo SearchServiceClient. El constructor de esta clase, recibe dos parámetros: el nombre del servicio que podemos obtener de la URL del servicio (https://%5Bnombreservicio%5D.search.windows.net) y la api-key para la autenticación del servicio. Ambos parámetros, para el ejemplo, los he almacenado en el App.Config de la aplicación de consola.

DeleteIndexIfExists: Una buena práctica, es comprobar si el índice existe previamente antes de crearlo y si es así, eliminarlo. De esto se encarga la función que vamos a ver a continuación:

private static void DeleteIndexIfExists(SearchServiceClient serviceClient, string indexName)
{
if (serviceClient.Indexes.Exists(indexName))
serviceClient.Indexes.Delete(indexName);
}

CreateIndexUsingNetSDK: Este método, crea un índice usando la SDK .NET de Azure Search.

private static void CreateIndexUsingNetSDK(SearchServiceClient serviceClient, string indexName)
{
var index = new Index()
{
Name = indexName,
Fields = new[]{
new Field("DocumentId",DataType.String) { IsKey = true, IsRetrievable = true, IsFilterable = true},
new Field("Name", DataType.String) { IsRetrievable = true, IsSearchable = true, IsFilterable = true},
new Field("Url", DataType.String) { IsRetrievable = true, IsSearchable = true, IsFilterable = true},
new Field("CreatedDate", DataType.String) { IsRetrievable = true, IsSearchable = true, IsFilterable = true}
}
};

serviceClient.Indexes.Create(index);
}

El método recibe como parámetros el objeto que hace referencia al servicio de búsqueda y el nombre del índice que vamos a crear. A continuación crea un objeto de tipo Index y le indica el nombre y los campos que va a tener dicho índice.

Cada campo se crea por medio de un objeto de tipo Field. El constructor de dicho objeto tiene dos parámetros, el nombre del campo y el tipo del mismo. Luego, podremos indicar otras propiedades de cada campo, como se ve en el ejemplo.

Por último, se crea el índice propiamente dicho con la llamada serviceClient.Indexes.Create(index) que vemos al final de la función.

CreateIndexUsingRESTAPI: La última función, crea un índice por medio de una llamada API REST.:

private static void CreateIndexUsingRESTAPI(string indexName)
{
string serviceName = ConfigurationManager.AppSettings["SearchServiceName"];
string apiKey = ConfigurationManager.AppSettings["ApiKey"];

string body = @"{
'name': '" + indexName + @"',
'fields': [
{'name': 'DocumentId', 'type': 'Edm.String', 'key': true, 'searchable': true},
{'name': 'Name', 'type': 'Edm.String'},
{'name': 'Url', 'type': 'Edm.String'},
{'name': 'CreatedDate', 'type': 'Edm.String'}
]
}";

using(var client = new HttpClient())
{
client.BaseAddress = new Uri("https://" + serviceName + ".search.windows.net");

client.DefaultRequestHeaders.Add("api-key", apiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = client.PostAsync("/indexes?api-version=2015-02-28", new StringContent(body,Encoding.UTF8, "application/json")).Result;

if(response.IsSuccessStatusCode)
{
Console.WriteLine("Index successfully created");
}
else
{
Console.WriteLine("HTTP Status: " + response.StatusCode.ToString() + " - Reason: " + response.ReasonPhrase);
}
}
}

Esta función en primer lugar, crea una cadena de texto con la estructura JSON del índice, y la almacena en la variable body. A continuación, establece la URL base del servicio REST de Azure Search (https://%5Bnombreservicio%5D.search.windows.net).

Tras esto, hace la llamada haciendo uso de la clase HttpClient. A esta llamada, de tipo POST y con la URL (/indexes?api-version=2015-02-28), hay que añadirle en las cabeceras la api-key del servicio.

Una vez que se recibe la respuesta, podremos comprobar si hemos recibido un estado correcto, en cuyo caso el índice se habrá creado correctamente, o no.

Probando el ejemplo
Una vez terminado el código, si depuramos el ejemplo nos aparece una pantalla como la siguiente:

test

Pulsando sobre cualquier de las dos opciones, veremos que se ejecuta correctamente, y si accedemos posteriormente al portal de Azure, al servicio de búsqueda, veremos que el índice se ha creado.

Captura de pantalla 2016-01-18 a las 20.44.17
Os voy a dejar algunos enlaces en los que me he basado y que os pueden resultar de interés.

https://azure.microsoft.com/en-us/services/search/

https://azure.microsoft.com/en-us/documentation/articles/search-get-started/

https://azure.microsoft.com/en-us/documentation/articles/search-howto-dotnet-sdk/

https://azure.microsoft.com/en-us/documentation/articles/search-create-service-portal/

Y esto es todo hasta aquí, en este post, hemos configurado y puesto en marcha el servicio de búsqueda creando los índices. En próximos posts, comenzaremos a indexar contenido y veremos cómo podemos hacerlo y consumiremos el servicio de búsqueda con todas las opciones de que disponemos para trabajar con el mismo.

Espero, como siempre, que os haya resultado interesante.

Hasta la próxima.

Anuncios

Primeros pasos con SharePoint 2016: La búsqueda híbrida

Muy buenas a todos,

Quiero seguir hoy profundizando en las características de SharePoint 2016, con uno de los aspectos más importantes que trae esta nueva versión, las búsquedas híbridas. En una anterior entrada os contaba mi primera experiencia con la versión preview de SharePoint 2016

Primeros pasos con SharePoint 2016

Uno de los objetivos principales que sigue esta nueva versión de SharePoint, es acercar a los usuarios a la nube. Para ello, incluye una serie de características que favorecen, para aquellos usuarios que no puedan hacer una migración completa a la misma, una experiencia que sirva como primer paso para ello. Una de las funcionalidades más destacadas es la de la búsqueda híbrida. Por medio de esta característica, podremos acceder desde la versión OnLine de SharePoint a contenido almacenado en nuestros servidores OnPremise.

En el post de hoy os quiero hablar de cómo configurar y poner en marcha la búsqueda híbrida en SharePoint 2016. Antes de continuar quiero puntualizar que la búsqueda híbrida, no es una característica exclusivamente nueva de SharePoint 2016, sino que desde la versión de SharePoint 2013 a partir de la actualización de Agosto de 2015, la tenemos disponible también. Además antes de esta actualización, SharePoint 2013 ya permitía de alguna forma la hibridación de la búsqueda (con la búsqueda híbrida federada), aunque no con el mismo nivel de integración que la actual solución de búsqueda híbrida.

¿En qué se diferencian la solución de búsqueda híbrida de SharePoint 2013 de esta nueva búsqueda híbrida?

En la solución de SharePoint 2013 (antes de la actualización de agosto como ya dije antes), la búsqueda híbrida federada, los resultados estaban organizados en dos índices, uno para SharePoint Server y otro para SharePoint OnLine y se clasificaban los contenidos de forma separada.

Captura de pantalla 2015-12-12 a las 23.09.09

Con la nueva solución de búsqueda híbrida, los resultados vienen en un único índice. El centro de búsqueda de SharePoint OnLine muestra y clasifica los resultados en un único bloque y calcula la relevancia, ranking y refinadores para todos los resultados independientemente de donde vengan.

 

Captura de pantalla 2015-12-12 a las 23.09.19

Configurando la búsqueda híbrida en SharePoint 2016

Antes de nada, os pongo en antecedentes. He creado una granja de servidores en Azure, con dos servidores, uno para SQLServer y otro para SharePoint. He instalado en el servidor de SharePoint la versión 2016 Beta 2 (será seguramente por temas de configuración o algún fallo mio, pero no me conseguí hacerla funcionar bien con la primera beta).

Para configurar la búsqueda híbrida, lo primero que tenemos que hacer es acceder al siguiente enlace y descargar el archivo que hay con la documentación para la configuración de la búsqueda híbrida.

https://connect.microsoft.com/office/Downloads

Siguiendo paso a paso el tutorial que viene en el pdf que encontraréis en el .zip que descargaréis, conseguiréis configurar completamente la búsqueda. Os voy a resumir los pasos que he llevado a cabo, todos sobre el servidor con SharePoint 2016 instalado, para que os hagáis una idea.

1.- Configurar la sincronización de los usuarios del Active Directory de mi granja OnPremise con Office 365, usando Azure Active Directory Sinchronization Services

Captura de pantalla 2015-11-28 a las 19.42.39Captura de pantalla 2015-11-28 a las 19.43.18Captura de pantalla 2015-11-28 a las 19.44.41

Tras configurar la sincronización, no debemos olvidar asignar a las nuevas cuentas que se han creado en Office 365 una licencia de Office 365 para que puedan ser usadas.

2.- En el archivo que descargamos hay dos scripts, ahora ejecutaremos el primero de los dos: CreateCloudSSA.ps1 que nos creará una aplicación de servicio de búsqueda con la configuración híbrida habilitada. En el caso de que se haya realizado correctamente todo el proceso, aparecerá un mensaje indicándolo. Este script nos pide como parámetros, los datos de nombre del servidor de SharePoint, cuenta del servicio de búsqueda, nombre de la aplicación de servicio y nombre del servidor de base de datos.

Captura de pantalla 2015-12-12 a las 23.48.18.png

3.- El siguiente paso es configurar la autenticación servidor a servidor, que permitirá las peticiones y respuestas entre nuestros servidores y la nube. Para ello, primero descargamos e instalamos, las dos siguientes herramientas: Microsoft Online Services Sign-In Assistant for IT Professionals RTW y Azure Active Directory Module for Windows PowerShell (64-bit version). Creo que con la Beta 2 se instalan automáticamente, porque no he tenido que instalarlas, ya las tenía en su versión más reciente y con la primera beta no ocurrió así, pero esto es solo una suposición.

4.- A continuación ejecutamos el segundo script de los disponibles: OnBoard-HybridSearch.ps1. En el que deberemos de indicar la Url de nuestro SharePoint OnLine.

Captura de pantalla 2015-12-12 a las 23.49.03.png

5.- Por último, creamos un origen de contenido, si no existe ya, y ejecutamos un rastreo completo. Una vez concluido y garantizado que todo funciona correctamente, podemos entrar en SharePoint OnLine para comprobarlo los resultados.

En mi caso, la primera vez que ejecuté el rastreo, obtuve el siguiente error en cada uno de los distintos elementos que el servicio de búsqueda encontró durante el mismo.

The item was reported as failed by the Search Content Service. It will be retried in the next incremental crawl. ( -1 (0): Parsing error parsing invalid JSON input stream. ; SearchID = FCAC6708-6982-4BB5-9A50-11FA405DAB2F )

Buscando en el foro oficial de búsqueda híbrida encontré el siguiente tema:

https://social.technet.microsoft.com/Forums/office/es-ES/a67fe60c-b8b2-4c89-b29b-e449daa8108c/announcement-error-when-crawling-sharepoint-content-with-cloud-hybrid-search-service-application-in?forum=CloudSSA

Donde justamente se habla de este error y desde el equipo de producto de Microsoft se daba la solución. Para corregir este bug, tendremos que usar los siguientes comandos de powershell.


$ssa=Get-SPEnterpriseSearchServiceApplication –Identity “Your SSA Name”
$ssa.SetProperty(“DisableGuidValueFlight”,1)
$ssa.SetProperty(“EnableGuidValueFlight”,0)
$ssa.Update()
Restart-Service SPSearchHostController
Restart-Service OSearch16

Una vez ejecutados los comandos, al volver a hacer el rastreo, ha funcionado todo correctamente.

Captura de pantalla 2015-12-12 a las 23.58.13

Probando la nueva búsqueda híbrida en SharePoint OnLine

Una vez que todo el proceso de configuración ha terminado, podemos ir a nuestra cuenta de SharePoint OnLine y probar si funciona todo correctamente. Para ello en el buscador, podemos hacer una búsqueda que nos devuelva los resultados procedentes de contenido externo. Podemos hacer la búsqueda usando una nueva propiedad que se agrega automáticamente en el contenido OnPremise de la siguiente forma, isexternalcontent:1. El resultado se muestra de la siguiente forma.

Captura de pantalla 2015-12-12 a las 20.10.37

Se puede ver cómo muestra los resultados que pertenecen al servidor de SharePoint OnPremise. Además otra de las posibilidades que nos ofrece esta nueva solución de búsqueda híbrida, es usar los contenidos de la versión OnPremise también en Delve.

Captura de pantalla 2015-12-12 a las 22.26.28.png

Os voy dejar algunos enlaces de interés donde podréis encontrar información interesante de esta temática.

El primer enlace es una artículo del último número de la revista CompartiMoss en donde encontraréis un tutorial muy completo de cómo configurar la búsqueda híbrida.

http://www.compartimoss.com/revistas/numero-26/la-busqueda-tambien-es-hibrida

El segundo enlace es el foro oficial sobre este tema de Microsoft

https://social.technet.microsoft.com/Forums/office/es-ES/home?forum=CloudSSA&filter=alllanguages

Este enlace es del blog oficial, con los pasos para hacer la configuración

http://blogs.msdn.com/b/spses/archive/2015/09/15/cloud-hybrid-search-service-application.aspx

Y esto es todo por hoy, espero que os haya gustado, es una característica muy interesante de SharePoint 2016 que quería mostraros. En los próximos días seguiré contándoos más sobre esta versión de SharePoint de la que en unos meses tendremos la versión definitiva.

Saludos.

 

Sharepoint-search: un componente Polymer para usar la búsqueda de SharePoint On-Line

Muy buenas a todos.

En una entrada anterior, os contaba cómo usar la búsqueda de SharePoint a través de su servicio API REST. El enlace ha dicha entrada es la siguiente:

Search Driven Development. Usando la API REST de SharePoint para el servicio de búsqueda

Al final de esta entrada os contaba que como objetivo, tenía el desarrollo de un componente Polymer que permitiera usar este servicio, algo que me resultaba muy útil e interesante. Después de varios días de trabajo, quería compartir con vosotros una primera “versión” de dicho componente. Aún queda trabajo por delante, pero ya hay un punto de partida funcional a partir del cual seguir trabajando.

El componente debía cumplir con los siguientes requisitos:

  • Permitir la posibilidad de usar refinadores.
  • Permitir la posibilidad de establecer opciones de ordenamiento.
  • Controlar la paginación y el número de resultados por página en los resultados de búsqueda.
  • Dar la posibilidad de estilar el contenido del componente en función de como se desee.

El componente “sharepoint-search” nos permite cubrir estos requisitos. Para usarlo, necesitaremos tener cargados los ficheros de Polymer y los propios del componente y utilizaremos la etiqueta de la siguiente manera:

<sharepoint-search tenant="organizer" clientid="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" refinement="author,size,created" ordination="size,created" pageElement="15">
</sharepoint-search>

Para que funcione correctamente, necesitaremos el clientID de una aplicación de Azure AD con los permisos para el servicio de búsqueda de SharePoint concedidos, y obviamente estar logado en nuestra aplicación contra esa aplicación de Azure AD, para ello podemos usar el componente para la autenticación que creé en una entrada anterior y seguir los correspondientes pasos para obtener el clientid:

Registrando una aplicación en Azure Active Directory

login-azuread: Un Componente Web con Polymer y Javascript ADAL

Además deberemos de configurar la aplicación de nuestra Azure AD para permitir el OAuth 2.0 implicit grant flow, lo haremos de la siguiente forma:

  • Acceder a la configuración de la aplicación de Azure AD correspondiente
  • Descargamos el manifiesto
  • Modificamos el parámetro oauth2AllowImplicitFlow dándole el valor true en lugar de false que tiene establecido inicialmente
  • Cargamos de nuevo el manifiesto modificado

El componente “sharepoint-search” permite configurar los siguientes parámetros:

  • tenant: Indicar el tenant al que nos queremos conectar
  • clientid: Clientid de la aplicación con los permisos adecuados
  • refinement: Propiedades para las cuales queremos obtener refinamiento
  • ordination: Propiedades por las que queremos hacer ordenación
  • pageElement: Número de elementos por página a mostrar

Una vez que lo añadimos, funciona como vemos a continuación.

sharepointsearchinit

sharepointsearchsearched

Por defecto, el componente nos muestra los resultados en una lista con el título del documento y la posibilidad de descargar el mismo. Aunque como se indica a continuación, en futuras mejoras, se trabajará en flexibilizar este aspecto del componente.

Os dejo el enlace a mi cuenta de GitHub donde podéis descargar el código del componente web y donde podréis encontrar información sobre cómo usarlo.

https://github.com/jcroav/sharepoint-search

Y esto es todo por hoy, este componente aún tiene áreas de mejora, a las que intentaré dedicarle tiempo en las próximas semanas. Os dejo algunas de las ideas:

  • El componente está pensado para que los resultados de búsqueda usen a su vez un subcomponente para ser mostrados, queda pendiente de desarrollar esa parte.
  • Completar el componente con la funcionalidad de sugerencias
  • Mejorar toda la parte de estilado
  • Refactorizar y trabajar sobre la optimiazación del código para hacer un componente más robusto

Como siempre, todo aquel que quiera colaborar, o quiera usar el componente que os he mostrado hoy para mejorarlo, es libre de hacerlo. El objetivo de estos desarrollos, a parte de para aprender a usar las funcionalidades de Office 365 y SharePoint On-Line, es contribuir a la comunidad.

Un saludo y espero que os sea útil

Search Driven Development. Usando la API REST de SharePoint para el servicio de búsqueda

Muy buenas a todos,

Recientemente he publicado algunos artículos sobre Search Driven Development para SharePoint Online y SharePoint 2013. Además hace poco tiempo tuve la oportunidad de participar en una mesa redonda con la gente de MadPoint en la que se hablaba de técnicas de desarrollo tanto para SharePoint OnLine como 2013 y Office 365. En esta mesa redonda salió la posibilidad de usar en los desarrollos la API REST del servicio de búsquedas de SharePoint y los nuevos frameworks de Javascript para crear nuestra propia solución basada en búsquedas.

Hasta entonces no había tenido la oportunidad de probar esta API REST, pero hoy os traigo una entrada en la que os quiero enseñar como usar las búsquedas a través de la API REST que nos proporciona esta versión de SharePoint.

En una primera parte de la entrada os enseñaré que consultas REST podemos hacer al servicio y lo que nos devuelve y a continuación veremos ejemplos de cómo utilizar el mismo en una app for SharePoint (o SharePoint Add-ins??).

Llamadas REST para el servicio de búsqueda

Uno de los aspectos importantes que tenemos que tener en cuenta cuando trabajamos con la API REST del servicio de búsqueda es que las consultas al mismo podemos hacerlas a través de peticiones GET y a través de peticiones POST. Esto es así, porque como es sabido por todos, las peticiones GET tienen limitaciones en cuanto al número de caracteres y puede ocurrir que una consulta que queramos hacer sobrepase ese límite, por lo que tendremos la oportunidad de usar las peticiones POST para superar dicha restricción.

A continuación voy a enseñar algunos ejemplos básicos de cómo utilizar ambos tipos de peticiones, aunque las posibilidades que tenemos a la hora de hacer las peticiones son muy extensas. Para esto os dejo el enlace a la referencia de la MSDN, donde podréis analizar al completo las opciones de la API.

https://msdn.microsoft.com/es-es/library/office/jj163876.aspx

Usando peticiones GET

Las peticiones GET se hacen a través de la siguiente URL:

http://servidor/_api/search/query

Consulta con un texto a buscar
/_api/search/query?querytext=’textoAconsultar’
Consulta usando una query
/_api/search/query?querytemplate='{searchterms} FileExtension: doc’
Usando la ordenación
/_api/search/query?querytext=’textAconsultar’&sortlist=’created:ascending,rank:descending,’
Indicando los refinadores a utilizar
/_api/search/query?querytext=’textAconsultar’&refiners=’author,size,fileExtension’
Filtrando la consulta usando el refinamiento
/_api/search/query?querytext=’textAconsultar’&refinementfilters=’fileExtension:equals(“docx”)’

Usando peticiones POST

Las peticiones POST se hacen a través de la siguiente URL:

http://servidor/_api/search/postquery

Consulta con un texto a buscar
{'request':
    { 
      '__metadata' : {'type' : 
                   'Microsoft.Office.Server.Search.REST.SearchRequest'},
      'Querytext' : 'ejemploAconsultar'
    }
}

Son muy importantes las mayúsculas y minúsculas en las consultas usando el método POST. Por ejemplo, en la consulta anterior, tenemos que usar ‘Querytext’ y no ‘QueryText’ o ‘querytext’ como hacemos en la consulta GET.

Estas consultas devuelven un JSON con toda la información necesaria de la búsqueda. Al igual que el resto de servicios REST, este de búsquedas es compatible con JSON Light, por lo que si lo deseeamos podemos obtener respuestas más ligeras y rápidas. Los resultados se encuentran en el objeto devuelto en:

data.body.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results (para GET)
data.body.d.postquery.PrimaryQueryResult.RelevantResult.Table.Rows.results (para POST)

Este elemento “results” json es un array que contiene una fila para cada uno de los resultados, en cada columna o celda de esta fila tenemos una de las propiedades del objeto devuelto. Para simplificar un poco la tarea, os voy a indicar en qué posición se encuentra la información que habitualmente es más importante de los objetos devueltos.

  • Posición 3: Title
  • Posición 4: Author
  • Posición 5: Size
  • Posición 6: Path
  • Posición 7: Description
  • Posición 8: Write
  • Posición 11: HitHighlightedSummary
  • Posición 18: FileExtension
  • Posición 31: FileType

El mismo servicio, si le hemos indicado para qué propiedades queremos obtener refinadores, nos devuelve los refinadores para esa búsqueda en:

data.body.d.query.PrimaryQueryResult.RefinementResults.Refiners.results

Esto nos devuelve, para cada refinador, un objeto de la siguiente forma:

{'Entries':
    {'results'
         {
             RefinementCount: count,
             RefinementToken: token,
             RefinementName: name,
             RefinementValue: value
         },
         {
             RefinementCount: count,
             RefinementToken: token,
             RefinementName: name,
             RefinementValue: value
         }
    },
  'Name':Refiner
}

Cada uno de los elementos contenidos en el objeto Entries, nos indica una opción de refinamiento para el refinado correspondiente. A continuación vamos a ver cómo he usado este servicio en una aplicación para SharePoint a modo de prueba.

Usando la API REST para búsquedas en una App for SharePoint

El ejemplo lo he realizado usando JQuery para manipular el DOM de la página del mismo. En primer lugar vamos a ver una captura de la aplicación para explicar que hace cada sección de la misma:

appsearchexample

En la aplicación que os quiero enseñar he hecho 5 ejemplos de como usar la API REST del servicio de búsqueda:

  • El primero ejemplo es una consulta usando GET a partir de una cadena de texto.
  • El segundo ejemplo es una consulta por POST a partir de una cadena de texto.
  • El tercer ejemplo usar una query para hacer la llamada al servicio de búsqueda por GET.
  • En el cuarto ejemplo se usa la ordenación.
  • El quinto ejemplo utiliza los refinadores.

Código del primer ejemplo

$("#searchbutton1").click(function () {

        var searchText = $("#searchbox1").val();

        executor.executeAsync({
            method: "GET",
            url: appweburl + "/_api/search/query?querytext='" + searchText + "'",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-type": "application/json;odata=verbose"
            },
            success: function (data) {

                var element = document.getElementById("resultsList1");

                $('#resultsList1 > li').remove();

                var jsonObject = JSON.parse(data.body);

                console.log(jsonObject);

                var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

                for(var i = 0; i < results.length; i++)
                {
                    var li = document.createElement("li");

                    li.innerText = results[i].Cells.results[3].Value + "
" + results[i].Cells.results[5].Value + "&nbsp;" + results[i].Cells.results[4].Value + "
" + results[i].Cells.results[11].Value;

                    element.appendChild(li);
                }
            },
            error: function (data) {
            }
        });

        return false;

    });

Código del segundo ejemplo

$("#searchbutton2").click(function () {

        var searchText = $("#searchbox2").val();

        executor.executeAsync({
            method: "POST",
            url: appweburl + "/_api/search/postquery",
            body: "{'request': { '__metadata' : {'type' : 'Microsoft.Office.Server.Search.REST.SearchRequest'}, 'Querytext' : '" + searchText + "' }}",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-type": "application/json;odata=verbose"
            },
            success: function (data) {

                var element = document.getElementById("resultsList2");

                $('#resultsList2 > li').remove();

                var jsonObject = JSON.parse(data.body);
                var results = jsonObject.d.postquery.PrimaryQueryResult.RelevantResults.Table.Rows.results;

                for (var i = 0; i < results.length; i++) {
                    var li = document.createElement("li");

                    li.innerText = results[i].Cells.results[3].Value;

                    element.appendChild(li);
                }
            },
            error: function (data) {
            }
        });

        return false;

    });

Código del tercer ejemplo

executor.executeAsync({
        method: "GET",
        url: appweburl + "/_api/search/query?querytemplate='{searchterms} FileExtension: doc'",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose"
        },
        success: function (data) {

            var element = document.getElementById("resultsList3");

            $('#resultsList3 > li').remove();

            var jsonObject = JSON.parse(data.body);

            var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

            for (var i = 0; i < results.length; i++) {
                var li = document.createElement("li");

                li.innerText = results[i].Cells.results[3].Value;

                element.appendChild(li);
            }
        },
        error: function (data) {
        }
    });

Los tres primeros ejemplos son muy similares. Entre el primero y el segundo la única diferencia es que una petición se hace por GET y otra petición se hace por POST. En el tercero, se vuelve a usar una consulta por GET pero en este caso en lugar de un texto lo que se pasa es una consulta como tal. Todos los ejemplos usan una lista para representar los resultados devueltos.

Código del cuarto ejemplo

$("#searchbutton4").click(function () {

        var searchText = $("#searchbox4").val();

        executor.executeAsync({
            method: "POST",
            url: appweburl + "/_api/search/postquery",
            body: "{'request': { '__metadata' : {'type' : 'Microsoft.Office.Server.Search.REST.SearchRequest'}, 'Querytext' : '" + searchText + "' }}",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-type": "application/json;odata=verbose"
            },
            success: function (data) {

                var element = document.getElementById("resultsList4");

                $('#resultsList4 > li').remove();

                var jsonObject = JSON.parse(data.body);
                var results = jsonObject.d.postquery.PrimaryQueryResult.RelevantResults.Table.Rows.results;

                for (var i = 0; i < results.length; i++) {
                    var li = document.createElement("li");

                    li.innerText = results[i].Cells.results[3].Value;

                    element.appendChild(li);
                }
            },
            error: function (data) {
            }
        });

        return false;

    });

    $("#orderbutton4").change(function () {

        var searchText = $("#searchbox4").val();
        var value = $("#orderbutton4").val();
        var order = "";

        if(value == "asc")
        {
            order = "created:ascending";
        }
        else
        {
            order = "created:descending";
        }

        executor.executeAsync({
            method: "GET",
            url: appweburl + "/_api/search/query?querytext='" + searchText + "'&sortlist='" + order + "'",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-type": "application/json;odata=verbose"
            },
            success: function (data) {

                var element = document.getElementById("resultsList4");

                $('#resultsList4 > li').remove();

                var jsonObject = JSON.parse(data.body);

                var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

                for (var i = 0; i < results.length; i++) {
                    var li = document.createElement("li");

                    li.innerText = results[i].Cells.results[3].Value + " " + results[i].Cells.results[8].Value;

                    element.appendChild(li);
                }
            },
            error: function (data) {
            }
        });

        return false;
    });

Básicamente este ejemplo funciona de la misma forma que los anteriores. Lo único extraordinario, tiene que ver con que queremos usar la ordenación por la propiedad “size” de los resultados. Hemos creado un combo donde podemos seleccionar, si queremos, orden ascendente y descendente para el tamaño. Lo que se ha hecho es crear otro evento que se dispara cuando cambia el valor seleccionado del combo para que se haga la ordenación. Para ello se añade a la consulta la parte correspondiente (sortlist) en función de si hemos seleccionado ascendente o descendente.

Código del último ejemplo

$("#searchbutton5").click(function () {

        var searchText = $("#searchbox5").val();

        executor.executeAsync({
            method: "GET",
            url: appweburl + "/_api/search/query?querytext='" + searchText + "'&refiners='author,size'",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-type": "application/json;odata=verbose"
            },
            success: function (data) {

                var element = document.getElementById("resultsList5");

                $('#resultsList5 > li').remove();

                var jsonObject = JSON.parse(data.body);

                console.log(jsonObject);

                var refiners = jsonObject.d.query.PrimaryQueryResult.RefinementResults.Refiners.results;

                $("#titlerefiner").text(refiners[0].Name);

                $.each(refiners[0].Entries.results, function (i, item) {
                    $('#valuerefiners').append($('<option>', {
                        value: refiners[0].Name + ":" + item.RefinementToken,
                        text: item.RefinementName
                    }));
                });

                var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

                for (var i = 0; i < results.length; i++) {
                    var li = document.createElement("li");

                    li.innerText = results[i].Cells.results[3].Value;

                    element.appendChild(li);
                }
            },
            error: function (data) {
            }
        });

        return false;

    });

    $("#valuerefiners").change(function () {

        var searchText = $("#searchbox5").val();
        var value = $("#valuerefiners").val();

        executor.executeAsync({
            method: "GET",
            url: appweburl + "/_api/search/query?querytext='" + searchText + "'&refinementfilters='" + value + "'",
            headers: {
                "accept": "application/json;odata=verbose",
                "content-type": "application/json;odata=verbose"
            },
            success: function (data) {

                var element = document.getElementById("resultsList5");

                $('#resultsList5 > li').remove();

                var jsonObject = JSON.parse(data.body);

                var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

                for (var i = 0; i < results.length; i++) {
                    var li = document.createElement("li");

                    li.innerText = results[i].Cells.results[3].Value;

                    element.appendChild(li);
                }
            },
            error: function (data) {
            }
        });

        return false;
    });

Este ejemplo igualmente es similar en cuanto a la forma en la que se representan los datos a los anteriores. La diferencia aquí es que a la petición le estamos indicando las propiedades de los resultados obtenidos por las que queremos poder refinar (Línea 7). Una vez que se obtienen los resultados, se carga uno de los refinadores en un combo preparado para tal efecto (Líneas 22 a 31), este combo se carga automáticamente con los valores de refinamiento obtenidos.

Además se añade otro evento para cuando ese combo cambia, con la selección de un refinamiento, de manera que se haga el filtrado correspondiente. Para ello, solo se añade a la petición el refinementfilters con el contenido a filtrar (Línea 58).

Conclusiones

Trabajar con las búsquedas de SharePoint OnLine y 2013 nos ofrece una gran cantidad de oportunidades a la hora de desarrollar de una forma sencilla, la API REST del servicio de búsqueda es muy potente y merece la pena tenerla en cuenta. En la entrada de hoy, os he introducido al uso de la misma y os he mostrado un ejemplo de cómo usarla en una ejemplo de una aplicación para SharePoint.

Y esto es todo por hoy, espero que os resulte interesante. ¿Cuál es el siguiente paso?, bueno, como sabéis me gusta mucho Polymer, y creo que podría ser interesante crear un componente Polymer que use este servicio de búsqueda de forma completa. Espero en breve compartirlo con vosotros y ponerlo disponible para que lo podáis utilizar.

Un saludo y hasta la próxima

Search Driven Development (IV): Cross-site publishing

Muy buenas a todos,

Tarde de lluvia aquí en Madrid y que mejor que ponerse a escribir en el blog para contar algunas cosas interesantes :). Hace unos meses escribí una serie de artículos en la que hablaba sobre “Search Driven Development”, como configurar nuestros sitios, la navegación basada en metadatos y todos los aspectos necesarios para tener un catálogo y elementos de ese catálogo sin escribir código. Aquí os dejo los enlaces en los que hablaba de todos esos temas.

Primeros Pasos con SharePoint OnLine: Search Driven Development

Search Driven Development en SharePoint (II): Catálogos y Elementos de Catálogo

Search Driven Development (III): El WebPart de Refinamiento

Preparando una ejemplo para una mesa redonda en la que colaboraré con la gente de MadPoint el próximo 7 de Mayo, he decidido retomar el artículo que me faltaba en esta serie y aquí os lo traigo. Me había quedado pendiente montar un entorno de cross-site publishing en el que en un sitio de publicación se publicarán los elementos del catálogo y en un sitio de consumo, se pudieran, usando los webpart de búsqueda, consumir esos elementos, incluyendo URLs amigables y navegación basada en metadatos. Todo esto puede parecer muy complejo, y que necesitará de muchísima configuración, pero ya veréis que es algo muy sencillo. La estructura que queremos conseguir es como la siguiente:

crosssiteschem

Esta característica de cross-site publishing es otra de las nuevas e interesantes funcionalidades que nos ofrece SharePoint 2013. Para conseguir esta configuración, vamos a llevar a cabo una serie de pasos que veremos a continuación, y que podremos aplicar tanto a SharePoint OnLine como SharePoint 2013 en su versión On-Premises. El objetivo de nuestro ejemplo, será crear un sitio de consumo que nos permita organizar una serie de productos de un catálogo en base a categorías y elementos que pertenecen a cada una de dichas categorías, y que dichas categorías sean las que definan la navegación de nuestro sitio, además los elementos serán publicados desde un sitio de publicación.

Creando las colecciones de sitios

El primer paso es crear las colecciones de sitios que vamos a utilizar en el ejemplo. En este caso crearemos dos, una primera de publicación y otra de consumo. Ambas colecciones de sitios las crearé bajo la plantilla de publicación, yo he llamado a una publicador y otro consumidor.

Las colecciones de sitio se crean de forma relativamente distintas si estamos en SharePoint OnLine o SharePoint 2013, yo las he creado en SharePoint OnLine para el ejemplo.

Captura de pantalla 2015-04-26 a las 20.19.13

Creando el almacén de términos

El siguiente paso, es definir el almacén de términos que va a categorizar los elementos que forman parte de nuestro catálogo, para ello accedemos a la administración de nuestro almacén de términos, que como sabéis está disponible tanto desde la administración central (o el panel de administración de SharePoint OnLine) como desde la configuración del sitio, y creamos la estructura, tiene que quedar de una forma similar a la siguiente:

Captura de pantalla 2015-04-26 a las 20.34.23

Configurando el sitio de publicación

Una vez que ya tenemos la categorización que tendrá nuestro catálogo de productos vamos a configurar el sitio de publicación con todos los elementos necesarios. Lo que vamos a hacer en el este sitio es lo siguiente:

  • El primer paso es activar en las “Características de la colección de sitios”, la característica “Publicación de colecciones entre sitios”.
  • Crear cuatro columnas de sitio: Una llamada Resumen de varias líneas de text, otra FechaPublicacion de tipo Fecha, otra llamada Clasificación de tipo metadatos administrados asociada al almacén creado en el apartado anterior y otras llamada autores que será de una línea de texto.
  • Crear un tipo de contenido que herede del Tipo de Contenido Elemento y al que se asocien las cuatro columnas anteriores y que se llamará “Libros”.
  • Crear una lista llamada “Productos”, para la que habilitaremos en la configuración de la misma la Administración de tipos de contenido y le asociaremos el tipo de contenido que acabamos de crear

Con esto ya tendremos preparado nuestro sitio de publicación. Este puede ser el momento para añadir algunos elementos a la lista que hemos creado también.

Creando el catálogo del sitio de publicación

Antes de pasar a la configuración del sitio de consumo, vamos a habilitar la lista para que pueda ser utilizada como catálogo. Para ello, dentro de la lista “Productos” que hemos creado, vamos a Configuración de la lista->Configuración del catálogo, esto nos llevará hasta la página que vemos a continuación.

Captura de pantalla 2015-04-26 a las 21.04.30

Aquí tendremos que indicar varias cosas, por un lado indicar que queremos habilitar esta lista para ser un catálogo, a continuación también indicaremos que columnas de la lista queremos que formen parte de la url del catálogo, y por último el campo, que normalmente se carga automáticamente, que establecerá la jerarquía de navegación. Una vez completados todos los aspectos de configuración, pulsamos en aceptar. Ahora ya podremos pasar a configurar el sitio de consumo. No obstante antes, en el apartado de Configuración Avanzada en la configuración de la lista indicaremos que se vuelva a indexar la lista en el próximo rastreo.

Configurando el sitio de consumo

Para terminar, nos vamos a la colección de sitios que hemos creado para trabajar como consumidor. Para configurar esta colección de sitios nos vamos a la configuración del sitios y entramos en Administrar conexiones del catálogo.

Captura de pantalla 2015-04-26 a las 21.13.46

Cuando entramos en esta opción pulsamos sobre Conectar a un catálogo y después seleccionamos la opción del catálogo que creamos en el sitio de publicación, observaremos que tenemos esa opción disponible.

managercatalog

Si todo lo hemos configurado correctamente, solo tendremos que configurar un aspecto, y es la raíz de la jerarquía de elementos, en donde tendremos que indicar la misma desde nuestro almacén de términos. Tras esto pulsamos sobre Aceptar y automáticamente todo estará funcionando correctamente como vemos en la figura siguiente.

Captura de pantalla 2015-04-26 a las 21.27.38

Como se puede observar automáticamente se ha creado toda la estructura de navegación usando el almacén de términos que habíamos creado. Además si accedemos, vemos que podemos entrar a todos los elementos de cada categoría, o si entramos a alguno de ellos al detalle. Es decir, configurando el catálogo toda la configuración de los webparts de búsqueda y de la navegación basada en metadatos se ha realizado automáticamente.

Captura de pantalla 2015-04-26 a las 21.32.24

Captura de pantalla 2015-04-26 a las 21.32.36

Lo único que faltaría sería usar los Display Templates para dar formato a las visualizaciones de los elementos. Para ello se puede usar lo que ya comenté en la entrada del post sobre ese tema:

Introducción al uso de Display Templates en SharePoint OnLine

Os dejo también un enlace con un tutorial muy detallado y completo sobre cómo configurar una solución Cross-Site Publishing y Search Driven Development.

http://blogs.technet.com/b/tothesharepoint/archive/2013/02/20/stage-1-create-site-collections-for-cross-site-publishing.aspx

Espero que os haya resultado interesante. Como os digo en la mesa redonda del evento que organiza MadPoint el próximo 7 de Mayo, mostraré el ejemplo completo funcionando, donde usaré ya los DisplayTemplates.

Os dejo también el enlace del evento por si alguien se quiere apuntar, se hablará no solo de SSD, sino de todas las formas de extender SharePoint OnLine y On-Premises, creo que va a ser muy interesante.

http://www.madpoint.net/2015/04/22/ciclo-de-mesas-redondas-opciones-de-desarrollo-en-sharepoint-y-office-365/

Un saludo a todos.

Ámbitos de Búsqueda en SharePoint 2010

Muy buenas a todos,

Últimamente, no venía siendo muy habitual que escribiera algo sobre SharePoint 2010, en los últimos meses estaba más centrado en los desarrollos para toda la suite de productividad de Microsoft, y así seguirá siendo en las próximas entradas, pero como en mi trabajo aún tengo proyectos basados en esta versión de SharePoint, quería compartir un aspecto en el que he profundizado relacionado con las búsquedas en SharePoint 2010.

Para todos los que conocéis o conocemos las características de SharePoint 2013 relacionadas con las búsquedas, habréis visto la cantidad de cosas que se pueden hacer, el Search Driven Development (SDD) nos permite cubrir muchos requisitos solo usando las opciones que nos proporcionan las búsquedas. De una forma muy sencilla, por medio de configuración de las búsquedas y usando los estándares de programación web (Javascript, Css y HTML) podemos hacer aplicaciones completas.

Si bien, con SharePoint 2010 no podemos alcanzar este nivel tan avanzado, si podemos hacer configuraciones interesantes para las búsquedas. En mi caso, para un proyecto necesitaba de un nivel importante de personalización de los resultados de búsqueda. Para este proyecto, al final, lo que pretendíamos es que las búsquedas solo devolvieran los elementos de unas listas determinadas de todo el proyecto. Para conseguir esto, al final, usamos el concepto de los “Ámbitos de Búsqueda” y “Grupos de Presentación”. Finalmente usando esto hemos conseguido el resultado justo que queríamos.

Vamos a ver cómo definir y usar los ámbitos de búsqueda en SharePoint 2010.

Definiendo el Ámbito de Búsqueda para SharePoint 2010

Lo primero que vamos a hacer es crear el ámbito de búsqueda para nuestro sitio. Los ámbitos de búsqueda, los podemos crear a nivel de Administración Central en la configuración de nuestro servicio de búsqueda, o bien en la configuración de la colección de sitios.

Para crear el ámbito a nivel de la configuración de la colección de sitios, hacemos lo siguiente:

image (5)

image (6)

Una vez en el apartado de ámbitos de búsqueda, pulsamos sobre crear o añadir un nuevo ámbito y nos aparece una pantalla como ésta.

image (7)

Aquí especificaremos el nombre y descripción del ámbito que vamos a crear y a qué página de resultados queremos que nos lleve. Una vez completada esta información, pulsamos sobre el botón Aceptar y ya tendremos el ámbito  creado para nuestra colección de sitios.

Añadiendo las reglas al ámbito de búsqueda

La potencia de los ámbitos de búsqueda se encuentra en las reglas que definamos para éstos. Aquí disponemos de bastante versatilidad y podemos definir mucha variedad de reglas. El siguiente paso tras crear el ámbito será asignarle las reglas que queremos para el mismo. Pulsamos sobre la opción de añadir reglas, y nos encontraremos una pantalla como la que veremos a continuación.

image (9)

Como podemos observar, podremos especificar restricciones para todas las propiedades administradas que hayan sido rastreadas y configuradas por nuestro servicio de búsqueda. Es posible que alguna en concreto no aparezca entre la opciones disponibles, pero sin embargo, si que se encuentre entre las propiedades administradas. Esto se debe a que seguramente no tenga la opción de disponible para usar en ámbitos activada. En mi caso, era lo que sucedía cuando quería usar en los ámbitos la propiedad de ContentType.

En el caso de que esto ocurra, y si queremos activar el uso en ámbitos para una determinada propiedad, nos vamos al servicio de búsqueda en la administración central de SharePoint y accedemos a las propiedades administradas rastreadas y mapeadas, seleccionamos aquella que queremos habilitar, damos a la opción editar y hacemos click sobre la casilla correspondiente como vemos en la siguiente imagen.

image (10)

image (11)

Cuando aceptamos y guardamos los cambios ya la tendremos disponible en las reglas de nuestro ámbito.

De esta forma podemos crear todas las reglas que deseemos y personalizar mucho los resultados de búsqueda que queremos obtener. En mi caso, por ejemplo, usando el valor de la propiedad ContentType, conseguimos limitar los resultados de búsqueda a una a serie de tipos de contenido concretos asociados a las listas cuyos elementos queríamos que aparecieran en las búsquedas, consiguiendo así cumplir con los requisitos preestablecidos para las búsquedas de dicho proyecto.

Creando el Grupo de Presentación

Para usar los ámbitos dentro de nuestro WebPart de búsqueda, vamos a asociar el mismo a un grupo de presentación, para luego establecer este mismo como predeterminado en dicho WebPart. Para ello, en el apartado de configuración de la colección de sitios, en los ámbitos de búsqueda, vamos a la opción de grupos de presentación y crear un nuevo grupo.

image (12)

En esta pantalla indicamos el nombre al grupo de presentación y los ámbitos que queremos que pertenezcan al mismo. Una vez hecho esto, lo que haremos será configurar el WebPart de Cuadro de Búsqueda o SearchBox WebPart para que funcione limitando las búsquedas a este ámbito que hemos creado.

Configurando el WebPart de Búsqueda

Lo primero que vamos a hacer es agregar un WebPart de Cuadro de Búsqueda en una página de nuestro sitio.

image (1)

Tras esto, vamos a las propiedades del WebPart para configurarlo. Es muy sencillo, por un lado, vamos a indicar el grupo de presentación que queremos que use este WebPart. Esto lo haremos en el apartado de varios tal y como vemos en la siguiente imagen.

image (2)

image (3)

Seleccionaremos el grupo de presentación que hemos creado en el apartado anterior. El último aspecto de configuración del WebPart está en la primera casilla de las propiedades del WebPart, con el modo de la lista desplegable, seleccionaremos la opción de “Mostrar pero no incluir ámbitos contextuales”, para que solo seleccione el ámbito que creamos y añadimos al Grupo de Presentación.

image (4)

En mi caso, no quería que el despegable se mostrara, aunque si que cogiera por defecto el ámbito que había creado, esto lo conseguí por medio de CSS, poniendo la propiedad display a none para la clase del despegable.

De esta forma, las búsquedas de mi aplicación se limitan por defecto al ámbito de los elementos que yo quiero, y se elimina todo lo demás, dando, en el caso de lo que queríamos conseguir, una mejor experiencia de usuario de una forma sencilla.

Esto, es lo que me ha parecido a mi más próximo a todo lo que podemos hacer con el SDD en SharePoint 2013. Evidentemente, no tenemos ni la navegación basada en metadatos ni las posibilidades de configuración de los WebPart de búsquedas, ni los display templates, pero nos permite bastantes personalizaciones.

Y esto es todo por hoy, poco a poco después de las vacaciones iré retomando la actividad del blog con cosas interesantes. Nos vemos pronto

Saludos a todos.

Número #23 de la revista CompartiMOSS y mi primera colaboración con la revista

Muy buenas a todos,

Ya está disponible un nuevo número de la revista CompartiMOSS, en este caso el número #23. Como siempre en esta revista encontraréis artículos muy interesantes relacionados con el mundo de SharePoint y os animos que la descarguéis y echéis un vistazo por su contenido.

http://www.compartimoss.com/revistas/numero-23

Aquí os dejo la relación de artículos que podréis encontrar en la revista, seguro que los encontraréis interesantes:

Búsqueda de datos empresariales en SharePoint 2013 – Parte I por Martin Luis Lopez Requena
Creación de un Chat para SharePoint con SignalR por José Antonio Fraga Sánchez
Introducción a los Grupos de Office 365 – Trabaja como una red – Parte II por Juan Carlos Gonzalez Martin
La importancia de diseñar y aplicar un buen uso de Gobernanza en nuestro entorno SharePoint 2013 por Francisco Ricardo Gil González
Las Aplicaciones High-Trust – II por Edin Kapic
Programando la Ribbon en SharePoint 2010 por Juan Pablo Pussacq
REST, WebAPI 2 y SharePoint 2013 – WebAPI y OData por Gustavo Velez
Administra mejor tus aplicaciones de servicio por Miguel Tabera Pacheco
Calculo de costes en Microsoft Azure por Fabian Calvo
Entrevista Jorge Castañeda Cano por Jorge Castañeda Cano
Integración Dynamics CRM 2015 con SharePoint por Demian Adolfo Raschkovan
Introducción al Search Driven Development en SharePoint Online y SharePoint 2013 por José Carlos Rodríguez Avilés
Novedades en Power BI por Javier Menéndez Pallo

En esta ocasión, como podréis ver, he tenido la oportunidad de colaborar con un artículo. Es mi primera aportación en una revista, y encima con la responsabilidad de hacerlo en CompartiMOSS, en la que escriben los mejores en la temática de SharePoint de habla Hispana.

El artículo trata sobre una temática de la que ya hablé en el blog, sobre Search Driven Development, es una breve introducción que sirve para conocer como usar este concepto y saber lo sencillo que es montar en SharePoint 2013 y OnLine un catálogo.

Como os digo, es mi primera aportación aunque espero que no sea la última, como decía al principio, os animo a descargarla y leerla.

Un saludo a todos