Un buscador en la nube : Azure Search (Parte 2)
22 Mar 2016En mi anterior post� os daba una visión general de que era y como funcionaba Azure Search, por lo que en las siguientes lineas vamos a ver más en detalle como crear índices, añadir documentos y realizar queries.
El objetivo es ver que opciones tenemos a la hora de realizar estos pasos y ver en detalle como realizar todas estas operaciones mediante el SDK de .Net para Azure Search de forma custom, es decir, sin enlazar ninguna fuente da datos.
Recordar que todas las operaciones también las podéis realizar mediante la REST Api.
Creación de índices
Un índice se compone de fields que pueden ser de los tipos siguientes:
Edm.String | Estándar string |
Collection(Edm.String) | Lista de string. El tamaño máximo de la colección es de 16 MB. |
Edm.Boolean | Valores: True/False |
Edm.Int32 | Entero de 32-bits |
Edm.Int64 | Entero de 64-bits |
Edm.Double | Número con precisión doble. En .Net sería el tipo Double. |
Edm.DateTimeOffset | Fecha representada en formato OData V4:� yyyy-MM-ddTHH:mm:ss.fffZ or yyyy-MM-ddTHH:mm:ss.fff[+|-]HH:mm |
Edm.GeographyPoint | Representa un punto en el mapa mundial. |
Es necesario añadir atributos a los fields. Añadiendo esto atributos lo que hacemos en darle un comportamiento dentro del servicio de forma que este pueda interactuar� con ellos� de la forma correcta al realizar las queries.
Estos atributos son:
- Retrievable –> El field será respuesta a la query lanzada.
- Filterable, Sortable, y� Facetable –> Indica como se puede usar el field en un filtro, ordenación o facet.
- Searchable –> el campo se incluye en la búsqueda full text. Solo los campos de tipo EDM.String deberían ser de este tipo.
Tenemos tres formas de crear índices y sus fields:
- Desde el portal.
- Vinculando una fuente de datos.
- Mediante código (SDK .Net o REST API)
Desde el portal
Entramos en nuestro Azure Search mediante el portal y añadimos un índice.
Una vez creado el índice añadimos sus fields
A partir de ese momento ya podríamos añadir documentos a nuestro índice.
Vinculando una fuente de datos
Podemos vincular tres fuentes de datos:
- SQLAzure o SQLServer in VM –> Vinculamos una tabla concreta a un índice. Nos crea los fields con las columnas de la tabla y debemos sincronizar los datos mediante un scheduler� � que puede lanzarse una vez, a una hora concreta, diariamente o custom. Más información:� https://azure.microsoft.com/en-us/documentation/articles/search-howto-connecting-azure-sql-database-to-azure-search-using-indexers-2015-02-28/
- DocumentDB –> En el caso de DocumentDB� en vez de vincular una tabla de BBDD, se vincula una collection de un� database de DocumentDB. Como en el cso de SQLAzure se deben sincronizar los datos y las opciones son las mismas que para SQLAzure. Más información en:� https://azure.microsoft.com/en-us/documentation/articles/documentdb-search-indexer/
- Blob storage (en preview) –> Igual que los anteriores, vinculas tu blob storage, crea los índices y sus fields y planificas la actualización de los datos. Los tipos de ficheros que actulmente acepta son: PDF, Microsoft Office formats, HTML, XML, ZIP, EML y Plain text files. Más infromación:� https://azure.microsoft.com/en-us/documentation/articles/search-howto-indexing-azure-blob-storage/
No entraré más en detalle en estas opciones dado que mi experiencia me indica que la mejor forma de tratar con índices y sus fields es hacerlo� manualmente. De esta forma no estas vinculado a una estructura concreta y puedes actualizar los documentos con tus propios procesos manipulando aquella información que necesites para guardarla como la necesites.
Mediante código
Lo primero que debemos hacer es añadir el paquete� NuGet de Azure Search.
Declaramos el índice y sus fields.
//Index Name var indexName = "example"; //Azure search credentials SearchServiceClient azureSearchService = new SearchServiceClient("your azure search name","your azure search key"); //Get azureSearch client for our index SearchIndexClient indexClient = azureSearchService.Indexes.GetClient(indexName); //Delete index if exist if (azureSearchService.Indexes.Exists(indexName)) { azureSearchService.Indexes.Delete(indexName); } //Create Index Model Index indexModel = new Index() { Name = indexName, Fields = new[] { new Field("ISBN", DataType.String) { IsKey = true, IsRetrievable = true, IsFacetable = false }, new Field("Titulo", DataType.String) {IsRetrievable = true, IsSearchable = true, IsFacetable = false }, new Field("Autores", DataType.Collection(DataType.String)) {IsSearchable = true, IsRetrievable = true, IsFilterable = true, IsFacetable = false }, new Field("FechaPublicacion", DataType.DateTimeOffset) { IsFilterable = true, IsRetrievable = false, IsSortable = true, IsFacetable = false }, new Field("Categoria", DataType.String) { IsFacetable = true, IsRetrievable = true } } };
Ahora creamos el índice:
//Create Index in AzureSearch var resultIndex = azureSearchService.Indexes.Create(indexModel);
Ahora ya tenemos creado el índice como podemos ver en el portal:
Añadiendo documentos
Una vez ya tenemos creado el índice y parametrizados sus índices podemos añadir documentos al índice.
Lo primero que debemos hacer es crear una clase con los mismos campos y tipos que los fields� de mi índice, en nuestro ejemplo.
public class BookModel { public string ISBN { get; set; } public string Titulo { get; set; } public List<string> Autores { get; set; } public DateTimeOffset FechaPublicacion { get; set; } public string Categoria { get; set; } }
Añadimos documentos a nuestro índice.
//De nuestro modelo obtenemos varios objetos a añadir. var listBooks = new BookModel().GetBooks(); //Add documents in our Index azureSearchService.Indexes.GetClient(indexName).Documents.Index(IndexBatch.MergeOrUpload<BookModel>(listBooks));
Si entramos en el portal y lanzamos una query veremos los documentos.
Realizando queries
Como hemos visto en el apartado anterior, podemos lazar queries desde el portal de forma que podemos realizar validación de datos.
Para realizar búsquedas necesitamos dos elementos:
- El texto a buscar. Se buscará el texto en aquellos fields
que hayamos indicado que son Searchables - Parámetros de búsqueda –> Valores de filtro, facet, ordenación, skip, _take, select…_En el siguiente link teneis toda la información de que podeis hacer:� https://msdn.microsoft.com/en-us/library/azure/dn798927.aspx
En el siguiente código vemos como añadir filtros, facets y ordenar por un campo.
// Execute search based on search text and optional filter var sp = new SearchParameters(); //Add Filter if (!String.IsNullOrEmpty(filter)) { sp.Filter = filter; } //Order if(order!=null && order.Count > 0) { sp.OrderBy = order; } //facets if (facets != null && facets.Count >; 0) { sp.Facets = facets; } //Search DocumentSearchResult<BookModel> response = indexClient.Documents.Search<BookModel>;(searchText, sp);
Por ejemplo si buscamos la palabra cloud obtenemos� el siguiente resultado:
Si la palabra de búsqueda es todo (*) y filtramos por un autor:
Si la palabra de búsqueda es todo (*) y � ordenamos por Fecha de publicación:
Si la palabra de búsqueda es todo (*) y traemos la facet de categorias
Conclusiones
La idea de este post es que os hagáis una idea de toda la potencia que tiene Azure Search y mostraros una pequeñas pinceladas de lo que se puede llegar ha hacer. Como habéis podido comprobar es un servicio fácil de configurar y de trabajar con él con una gran variedad de opciones y configuraciones para poder ajustarlo a nuestras necesidades.
En el próximo post realizaré la última entrada sobre Azure Search donde entraremos más en detalle� scoring y suggestions.
El código lo podéis descargar y ver de:� https://github.com/bermejoblasco/AzureSearch