Este documento proporciona un tutorial paso a paso para crear, cargar y consultar un índice de Azure Cognitive Search utilizando Python y Jupyter Notebooks. Explica cómo crear un índice con un esquema definido, cargar documentos de muestra y realizar consultas utilizando diferentes parámetros como filtros, ordenación y paginación. Finalmente, muestra cómo eliminar el índice creado para liberar espacio.
1. Tutorial #1: Crea un índice de Azure Cognitive Search en Python
utilizando Jupyter Notebooks
En este primer tutorial se explica cómo crear, cargar y consultar un índice de Azure Cognitive
Search mediante Python y las API REST del servicio cognitivo. La ejecución es en un ambiente
Anaconda 3.x, pero de forma alternativa puedes utilizar Azure Jupyter Notebooks, un servicio
gratuito para ejecución de scripts de Python en la nube.
NOTA: Este taller está basado en el tutorial localizado en la documentación oficial.
Pre-requisitos:
Anaconda 3.x, el cual contiene Python 3.x e instancias de Jupyter Notebook
O también puedes utilizar el servicio de Azure Jupyter Notebooks.
Un recurso de Azure Cognitive Search.
2. Paso 1. Creación del recurso de Azure Cognitive Search
a) Accede al portal de Azure (https://portal.azure.com) y busca el recurso Azure Cognitive
Search:
b) Da clic en el botón Create.
3. c) Llena los datos solicitados y da clic en Review + create:
Grupo de recursos: taller2-rg (nuevo)
URL: Debe ser un nombre único/universal
Ubicación: West US 2
Esquema de precio: Gratuito
4. d) Da clic en Create.
e) Una vez generado el recurso, accede a él (desde las notificaciones o localízalo en tu
suscripción)
5. f) En la sección Keys, copia la llave que aparece en debajo de Primary admin key.
g) También toma nota del nombre de tu recurso (taller-search-lb en este caso).
6. Paso 2. Creación del proyecto de Azure Notebooks.
a) Ingresa a Azure Notebooks (https://notebooks.azure.com)
b) Da clic en My Projects y da clic en New Project.
7. c) El nombre del proyecto es Taller-IA02. Llena el resto de los datos solicitados de la
siguiente manera:
d) Da clic en el botón + y selecciona Notebook:
8. e) El nombre del cuaderno de trabajo es search-demo.ipynb,yellenguaje es Python3.5. Da
clic en New.
9. Paso 3. Creación del índice:
a) Preparación
A continuación, veamos el código para crear un índice de búsqueda y filtrar información. En la
primer celda carga las bibliotecas para trabajar con JSON y formular las solicitudes HTTP:
import json
import requests
from pprint import pprint
En la segunda celda, introduce los elementos de solicitud que serán constantes en cada solicitud.
Reemplaza el nombre del servicio de búsqueda (YOUR-SEARCH-SERVICE-NAME) y la clave de API
de administración (YOUR-ADMIN-API-KEY) por los valores obtenidos al crear el recurso de Azure
Cognitive Search.
endpoint = 'https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/'
api_version = '?api-version=2019-05-06'
headers = {'Content-Type': 'application/json',
'api-key': '<YOUR-ADMIN-API-KEY>' }
En la tercera celda, realiza la petición http de tipo GET que tiene como objetivo la colección de
índices del servicio de búsqueda y selecciona la propiedad de nombre de los índices existentes.
url = endpoint + "indexes" + api_version + "&$select=name"
response = requests.get(url, headers=headers)
index_list = response.json()
pprint(index_list)
Ejecuta estas 3 celdas:
10. b) Creación del índice
Los elementos necesarios de un índice incluyen un nombre, una colección de campos y una clave.
La colección de campos define la estructura de un documento. Cada campo tiene nombre, tipo y
atributos que determinan cómo se usa el campo (por ejemplo, si es texto completo que se puede
buscar, filtrar o recuperar en los resultados de búsqueda). Dentro de un índice, uno de los campos
de tipo Edm.String se debe designar como la clave para la identidad del documento.
Este índice se denomina "hotels-quickstart" y tiene las definiciones de campo que aparecen a
continuación. Pega el siguiente código en una celda para proporcionar el esquema.
index_schema = {
"name": "hotels-quickstart",
"fields": [
{"name": "HotelId", "type": "Edm.String", "key": "true", "filterable":
"true"},
{"name": "HotelName", "type": "Edm.String", "searchable": "true",
"filterable": "false", "sortable": "true", "facetable": "false"},
{"name": "Description", "type": "Edm.String", "searchable": "true",
"filterable": "false", "sortable": "false", "facetable": "false", "analyzer":
"en.lucene"},
{"name": "Description_fr", "type": "Edm.String", "searchable": "true",
"filterable": "false", "sortable": "false", "facetable": "false", "analyzer":
"fr.lucene"},
{"name": "Category", "type": "Edm.String", "searchable": "true",
"filterable": "true", "sortable": "true", "facetable": "true"},
{"name": "Tags", "type": "Collection(Edm.String)", "searchable": "true",
"filterable": "true", "sortable": "false", "facetable": "true"},
{"name": "ParkingIncluded", "type": "Edm.Boolean", "filterable": "true",
"sortable": "true", "facetable": "true"},
{"name": "LastRenovationDate", "type": "Edm.DateTimeOffset", "filterable":
"true", "sortable": "true", "facetable": "true"},
{"name": "Rating", "type": "Edm.Double", "filterable": "true", "sortable":
"true", "facetable": "true"},
{"name": "Address", "type": "Edm.ComplexType",
"fields": [
{"name": "StreetAddress", "type": "Edm.String", "filterable": "false",
"sortable": "false", "facetable": "false", "searchable": "true"},
{"name": "City", "type": "Edm.String", "searchable": "true", "filterable":
"true", "sortable": "true", "facetable": "true"},
{"name": "StateProvince", "type": "Edm.String", "searchable": "true",
"filterable": "true", "sortable": "true", "facetable": "true"},
{"name": "PostalCode", "type": "Edm.String", "searchable": "true",
"filterable": "true", "sortable": "true", "facetable": "true"},
{"name": "Country", "type": "Edm.String", "searchable": "true",
"filterable": "true", "sortable": "true", "facetable": "true"}
]
}
]
}
11. En otra celda,realiza lasolicitudhttp de tipo POST que tiene como objetivo lacolección de índices
del servicio de búsqueda y crea un índice en función del esquema de índice proporcionado en la
celda anterior.
url = endpoint + "indexes" + api_version
response = requests.post(url, headers=headers, json=index_schema)
index = response.json()
pprint(index)
Ejecuta estas dos celdas:
12. c) Carga de documentos:
Para insertar documentos, usa una solicitud HTTP POST al punto de conexión de la dirección URL
del índice.
En una celda nueva, proporciona 4 documentos que se ajustan al esquema de índice. Especifica
una acción de carga para cada documento.
documents = {
"value": [
{
"@search.action": "upload",
"HotelId": "1",
"HotelName": "Secret Point Motel",
"Description": "The hotel is ideally located on the main commercial artery of
the city in the heart of New York. A few minutes away is Time's Square and the
historic centre of the city, as well as other places of interest that make New
York one of America's most attractive and cosmopolitan cities.",
"Description_fr": "L'hôtel est idéalement situé sur la principale artère
commerciale de la ville en plein cœur de New York. A quelques minutes se trouve
la place du temps et le centre historique de la ville, ainsi que d'autres lieux
d'intérêt qui font de New York l'une des villes les plus attractives et
cosmopolites de l'Amérique.",
"Category": "Boutique",
"Tags": [ "pool", "air conditioning", "concierge" ],
"ParkingIncluded": "false",
"LastRenovationDate": "1970-01-18T00:00:00Z",
"Rating": 3.60,
"Address": {
"StreetAddress": "677 5th Ave",
"City": "New York",
"StateProvince": "NY",
"PostalCode": "10022",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "2",
"HotelName": "Twin Dome Motel",
"Description": "The hotel is situated in a nineteenth century plaza, which
has been expanded and renovated to the highest architectural standards to create
a modern, functional and first-class hotel in which art and unique historical
elements coexist with the most modern comforts.",
"Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été
agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel
moderne, fonctionnel et de première classe dans lequel l'art et les éléments
historiques uniques coexistent avec le confort le plus moderne.",
"Category": "Boutique",
"Tags": [ "pool", "free wifi", "concierge" ],
"ParkingIncluded": "false",
13. "LastRenovationDate": "1979-02-18T00:00:00Z",
"Rating": 3.60,
"Address": {
"StreetAddress": "140 University Town Center Dr",
"City": "Sarasota",
"StateProvince": "FL",
"PostalCode": "34243",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "3",
"HotelName": "Triple Landscape Hotel",
"Description": "The Hotel stands out for its gastronomic excellence under the
management of William Dough, who advises on and oversees all of the Hotel's
restaurant services.",
"Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été
agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel
moderne, fonctionnel et de première classe dans lequel l'art et les éléments
historiques uniques coexistent avec le confort le plus moderne.",
"Category": "Resort and Spa",
"Tags": [ "air conditioning", "bar", "continental breakfast" ],
"ParkingIncluded": "true",
"LastRenovationDate": "2015-09-20T00:00:00Z",
"Rating": 4.80,
"Address": {
"StreetAddress": "3393 Peachtree Rd",
"City": "Atlanta",
"StateProvince": "GA",
"PostalCode": "30326",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "4",
"HotelName": "Sublime Cliff Hotel",
"Description": "Sublime Cliff Hotel is located in the heart of the historic
center of Sublime in an extremely vibrant and lively area within short walking
distance to the sites and landmarks of the city and is surrounded by the
extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff
is part of a lovingly restored 1800 palace.",
"Description_fr": "Le sublime Cliff Hotel est situé au coeur du centre
historique de sublime dans un quartier extrêmement animé et vivant, à courte
distance de marche des sites et monuments de la ville et est entouré par
l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments.
Sublime Cliff fait partie d'un Palace 1800 restauré avec amour.",
"Category": "Boutique",
"Tags": [ "concierge", "view", "24-hour front desk service" ],
"ParkingIncluded": "true",
"LastRenovationDate": "1960-02-06T00:00:00Z",
14. "Rating": 4.60,
"Address": {
"StreetAddress": "7400 San Pedro Ave",
"City": "San Antonio",
"StateProvince": "TX",
"PostalCode": "78216",
"Country": "USA"
}
}
]
}
En otra celda, realiza la solicitud http POST que tiene como destino la colección de documentos
del índice hotels-quickstart y envía los documentos proporcionados en el paso anterior.
url = endpoint + "indexes/hotels-quickstart/docs/index" + api_version
response = requests.post(url, headers=headers, json=documents)
index_content = response.json()
pprint(index_content)
Ejecuta ambas celdas:
15.
16. d) Búsqueda en índices:
Este paso muestra cómo realizar consultas en un índice con la API de REST de Azure Cognitive
Search.
En una celda, proporciona una expresión de consulta que ejecute una búsqueda vacía
(búsqueda=*), la cual devuelve una lista no clasificada (puntuación de búsqueda=1,0) de
documentos arbitrarios. De forma predeterminada, Azure Cognitive Search devuelve 50
resultados cada vez.
Al ser estructurada, esta consulta devuelve la estructura y los valores del documento entero.
Agrega $count=true para obtener un recuento de todos los documentos de los resultados.
searchstring = '&search=*&$count=true'
url = endpoint + "indexes/hotels-quickstart/docs" + api_version + searchstring
response = requests.get(url, headers=headers, json=searchstring)
query = response.json()
pprint(query)
Ejecuta y observa los resultados:
17. En una celda nueva, proporciona el código siguiente para buscar los términos "hoteles" y "wifi".
Agrega $select para especificar qué campos quiere incluir en los resultados de búsqueda.
searchstring = '&search=hotels wifi&$count=true&$select=HotelId,HotelName'
url = endpoint + "indexes/hotels-quickstart/docs" + api_version + searchstring
response = requests.get(url, headers=headers, json=searchstring)
query = response.json()
pprint(query)
Si ejecutas la celda, el resultado se muestra a continuación:
18. A continuación, aplica una expresión $filter que seleccione solo aquellos hoteles con una
clasificación superior a 4.
searchstring = '&search=*&$filter=Rating gt
4&$select=HotelId,HotelName,Description,Rating'
url = endpoint + "indexes/hotels-quickstart/docs" + api_version + searchstring
response = requests.get(url, headers=headers, json=searchstring)
query = response.json()
pprint(query)
Ejecuta y observa el resultado:
19. De forma predeterminada, el motor de búsqueda devuelve los 50 documentos más importantes,
pero puedes usar las subcláusulas TOP y SKIP para agregar paginación y elegir el número de
documentos en cada resultado. Esta consulta devuelve dos documentos en cada conjunto de
resultados.
searchstring = '&search=boutique&$top=2&$select=HotelId,HotelName,Description'
url = endpoint + "indexes/hotels-quickstart/docs" + api_version + searchstring
response = requests.get(url, headers=headers, json=searchstring)
query = response.json()
pprint(query)
Ejecuta la celda para comprobar:
20. En este último ejemplo, use $orderby para ordenar los resultados por ciudad. En este ejemplo se
incluyen los campos de la colección de direcciones.
searchstring = '&search=pool&$orderby=Address/City&$select=HotelId, HotelName,
Address/City, Address/StateProvince'
url = endpoint + "indexes/hotels-quickstart/docs" + api_version + searchstring
response = requests.get(url, headers=headers, json=searchstring)
query = response.json()
pprint(query)
21. e) Limpieza
Si has completado todo lo necesario para crear el índice, puedes eliminarlo con las siguientes
líneas de código:
url = endpoint + "indexes/hotels-quickstart" + api_version
response = requests.delete(url, headers=headers)
Eliminar índices innecesarios libera espacio. Confirma el borrado del índice ejecutando el
siguiente script que lista todos los índices en tu servicio de búsqueda. Si hotels-quickstart no está
listado, has eliminado exitosamente el índice creado en este tutorial.
url = endpoint + "indexes" + api_version + "&$select=name"
response = requests.get(url, headers=headers)
index_list = response.json()
pprint(index_list)
Ejecuta ambas celdas y observa el resultado: