

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Tutorial: Creación de una aplicación de búsqueda con Amazon OpenSearch Service
<a name="search-example"></a>

Una forma habitual de crear una aplicación de búsqueda con Amazon OpenSearch Service consiste en utilizar formularios web para enviar las consultas de los usuarios a un servidor. Luego, puedes autorizar al servidor a que lo llame OpenSearch APIs directamente y hacer que el servidor envíe las solicitudes al OpenSearch Servicio. Pero si desea escribir un código del lado del cliente que no dependa de un servidor, debe compensar los riesgos de seguridad y rendimiento. No es aconsejable permitir el acceso público y sin firma al OpenSearch APIs . Los usuarios pueden acceder a puntos de conexión no protegidos o influir en el rendimiento del clúster a través de consultas demasiado complejas (o demasiadas consultas).

En este capítulo se presenta una solución: utilice Amazon API Gateway para restringir a los usuarios a un subconjunto de ellos OpenSearch APIs y AWS Lambda para firmar las solicitudes de API Gateway al OpenSearch servicio.

![\[Diagrama de flujo de la aplicación de búsqueda.\]](http://docs.aws.amazon.com/es_es/opensearch-service/latest/developerguide/images/search-application-diagram.png)


**nota**  
Se aplican precios estándar de API Gateway y Lambda, pero dentro del uso limitado de este tutorial, los costos deben ser insignificantes.

## Requisitos previos
<a name="search-example-prereq"></a>

Un requisito previo para este tutorial es un dominio OpenSearch de servicio. Si aún no tiene uno, siga los pasos que se indican en [Crear un dominio de OpenSearch servicio](gsgcreate-domain.md) para crear uno.

## Paso 1: Indexe los datos de muestra
<a name="search-example-index"></a>

Descargue [sample-movies.zip](samples/sample-movies.zip), descomprímalo y utilice la operación [\$1bulk](https://opensearch.org/docs/latest/api-reference/document-apis/bulk/) de la API para agregar 5000 documentos al índice `movies`:

```
POST https://search-my-domain.us-west-1.es.amazonaws.com/_bulk
{ "index": { "_index": "movies", "_id": "tt1979320" } }
{"directors":["Ron Howard"],"release_date":"2013-09-02T00:00:00Z","rating":8.3,"genres":["Action","Biography","Drama","Sport"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg","plot":"A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.","title":"Rush","rank":2,"running_time_secs":7380,"actors":["Daniel Brühl","Chris Hemsworth","Olivia Wilde"],"year":2013,"id":"tt1979320","type":"add"}
{ "index": { "_index": "movies", "_id": "tt1951264" } }
{"directors":["Francis Lawrence"],"release_date":"2013-11-11T00:00:00Z","genres":["Action","Adventure","Sci-Fi","Thriller"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTAyMjQ3OTAxMzNeQTJeQWpwZ15BbWU4MDU0NzA1MzAx._V1_SX400_.jpg","plot":"Katniss Everdeen and Peeta Mellark become targets of the Capitol after their victory in the 74th Hunger Games sparks a rebellion in the Districts of Panem.","title":"The Hunger Games: Catching Fire","rank":4,"running_time_secs":8760,"actors":["Jennifer Lawrence","Josh Hutcherson","Liam Hemsworth"],"year":2013,"id":"tt1951264","type":"add"}
...
```

Tenga en cuenta que lo anterior es un comando de ejemplo con un pequeño subconjunto de datos disponibles. Para realizar la operación `_bulk`, debe copiar y pegar todo el contenido del archivo `sample-movies`. Para obtener más instrucciones, consulte [Opción 2: cargar varios documentos](gsgupload-data.md#gsgmultiple-document).

También puede utilizar el siguiente comando curl para conseguir el mismo resultado: 

```
curl -XPOST -u 'master-user:master-user-password' 'domain-endpoint/_bulk' --data-binary @bulk_movies.json -H 'Content-Type: application/json'
```

## Paso 2: crear e implementar una función de Lambda
<a name="search-example-lambda"></a>

Antes de crear su API en API Gateway, cree la función de Lambda a la que pasa las solicitudes.

### Crear la función de Lambda
<a name="sample-lamdba-python"></a>

En esta solución, API Gateway pasa las solicitudes a una función de Lambda, que consulta el OpenSearch servicio y devuelve los resultados. Dado que esta función de ejemplo utiliza bibliotecas externas, debe crear un paquete de implementación y cargarlo en Lambda.

**Creación del paquete de implementación**

1. Abra un símbolo del sistema y cree un directorio del proyecto `my-opensearch-function`. Por ejemplo, en macOS:

   ```
   mkdir my-opensearch-function
   ```

1. Desplácese hasta el directorio del proyecto `my-sourcecode-function`.

   ```
   cd my-opensearch-function
   ```

1. Copie el contenido del siguiente código Python de ejemplo y guárdelo en un nuevo archivo denominado `opensearch-lambda.py`. Añada su región y el punto de conexión del host al archivo.

   ```
   import boto3
   import json
   import requests
   from requests_aws4auth import AWS4Auth
   
   region = '' # For example, us-west-1
   service = 'es'
   credentials = boto3.Session().get_credentials()
   awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)
   
   host = '' # The OpenSearch domain endpoint with https:// and without a trailing slash
   index = 'movies'
   url = host + '/' + index + '/_search'
   
   # Lambda execution starts here
   def lambda_handler(event, context):
   
       # Put the user query into the query DSL for more accurate search results.
       # Note that certain fields are boosted (^).
       query = {
           "size": 25,
           "query": {
               "multi_match": {
                   "query": event['queryStringParameters']['q'],
                   "fields": ["title^4", "plot^2", "actors", "directors"]
               }
           }
       }
   
       # Elasticsearch 6.x requires an explicit Content-Type header
       headers = { "Content-Type": "application/json" }
   
       # Make the signed HTTP request
       r = requests.get(url, auth=awsauth, headers=headers, data=json.dumps(query))
   
       # Create the response and add some extra content to support CORS
       response = {
           "statusCode": 200,
           "headers": {
               "Access-Control-Allow-Origin": '*'
           },
           "isBase64Encoded": False
       }
   
       # Add the search results to the response
       response['body'] = r.text
       return response
   ```

1. Instale las bibliotecas externas en un nuevo directorio `package`.

   ```
   pip3 install --target ./package boto3
   pip3 install --target ./package requests
   pip3 install --target ./package requests_aws4auth
   ```

1. Cree un paquete de implementación con las bibliotecas instaladas en la raíz. El siguiente comando genera un archivo `my-deployment-package.zip` en el directorio de su proyecto. 

   ```
   cd package
   zip -r ../my-deployment-package.zip .
   ```

1. Agregue el archivo `opensearch-lambda.py` a la raíz del archivo zip.

   ```
   cd ..
   zip my-deployment-package.zip opensearch-lambda.py
   ```

Para obtener más información sobre cómo crear funciones de Lambda y paquetes de implementación, consulte [Deploy Python Lambda functions with .zip file archives](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html) en la *Guía para desarrolladores de AWS Lambda * y [Crear el paquete de implementación de Lambda](integrations-s3-lambda.md#integrations-s3-lambda-deployment-package) en esta guía.

Cómo crear la función usando la consola de Lambda

1. [Diríjase a la consola Lambda de su https://console.aws.amazon.com/lambda/ casa.](https://console.aws.amazon.com/lambda/home ) En el panel de navegación izquierdo, seleccione **Funciones**.

1. Seleccione **Crear función**.

1. Configure los siguientes campos:
   + Nombre de función: opensearch-function
   + Tiempo de ejecución: Python 3.9
   + Arquitectura: x86\$164

   Mantenga todas las demás opciones predeterminadas y elija **Crear función**. 

1. En la sección **Código fuente** de la página de resumen de la función, seleccione el menú desplegable **Cargar desde** y seleccione el **archivo .zip**. Busque el archivo `my-deployment-package.zip` que ha creado y seleccione **Guardar**.

1. El *controlador* es el método de su código de función que procesa eventos. En **Configuración de tiempo de ejecución**, seleccione **Editar** y cambie el nombre del controlador de acuerdo con el nombre del archivo en el paquete de implementación donde se encuentra la función de Lambda. Como el archivo se denomina `opensearch-lambda.py`, cambie el nombre del controlador a `opensearch-lambda.lambda_handler`. Para más información, consulte [Controlador de funciones de Lambda en Python](https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html).

## Paso 3: crear la API en API Gateway
<a name="search-example-api"></a>

El uso de API Gateway le permite crear una API más limitada y simplifica el proceso de interacción con la OpenSearch `_search` API. API Gateway le permite habilitar las características de seguridad, como la autenticación de Amazon Cognito y la limitación controlada. Realice los siguientes pasos para crear e implementar una API:

### Crear y configurar la API
<a name="create-api"></a>

Para crear una API mediante la consola de API Gateway

1. Dirígete a la consola de API Gateway en [https://console.aws.amazon.com/apigateway/casa](https://console.aws.amazon.com/apigateway/home ). En el panel de navegación izquierdo, selecciona **APIs**.

1. Localice **API de REST** (no privado) y elija **Crear**.

1. En la siguiente página, busque la sección **Crear nueva API** y asegúrese de que **Nueva API** esté seleccionada.

1. Configure los siguientes campos:
   + Nombre de la API: **opensearch-api**
   + Descripción: **API pública para buscar un dominio OpenSearch de Amazon Service**
   + Tipo de punto de conexión: **Regional**

1. Seleccione **Crear API**. 

1. Seleccione **Acciones** y **Crear método**.

1. Seleccione **GET** (Obtener) en el menú desplegable y haga clic en la marca de verificación para confirmar.

1. Configure los siguientes ajustes y, a continuación, elija **Guardar**:


| Opción | Valor | 
| --- | --- | 
| Tipo de integración | Función de Lambda | 
| Usar integración de proxy de Lambda | Sí | 
| Región de Lambda | us-west-1 | 
| Función de Lambda | opensearch-lambda | 
| Usar tiempo de espera predeterminado | Sí | 

### Configuración de la solicitud de método
<a name="method-request"></a>

Seleccione **Solicitud de método** y configure los siguientes ajustes:


| Opción | Valor | 
| --- | --- | 
| Autorización | NONE | 
| Validador de solicitud |  Validar parámetros de cadena de consulta y encabezados   | 
| Clave de API requerida | falso | 

En **Parámetros de cadena de consulta de URL**, seleccione **Añadir cadena de consulta** y configure el siguiente parámetro:


| Opción | Valor | 
| --- | --- | 
| Name | q | 
| Obligatorio |  Sí  | 

### Implemente la API y configure una etapa
<a name="deploy-api"></a>

 La consola de API Gateway le permite implementar una API creando una implementación y asociándola a una etapa nueva o una existente. 

1. Seleccione **Acciones** e **Implementar API**.

1. Para **Etapa de implementación** elija **Nueva etapa** y nombre la etapa `opensearch-api-test`.

1. Seleccione **Implementar**.

1. Configure los siguientes ajustes en el editor de etapas y, a continuación, elija **Guardar los cambios**:


| Opción | Valor | 
| --- | --- | 
| Habilitar limitación controlada | Sí | 
| Tarifa |  1 000  | 
| Ráfagas | 500 | 

Estos ajustes configuran una API que solo tiene un método: una solicitud `GET` al punto de conexión raíz (`https://some-id.execute-api.us-west-1.amazonaws.com/search-es-api-test`). La solicitud requiere un solo parámetro (`q`), la cadena de consulta que se busca. Cuando se llama, el método pasa la solicitud a Lambda, que ejecuta la función `opensearch-lambda`. Para más información, consulte [Creación de una API en Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) e [Implementación de una API de REST en Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html).

## Paso 4: (opcional) modificar la política de acceso a dominios
<a name="search-example-perms"></a>

Su dominio de OpenSearch servicio debe permitir que la función Lambda realice `GET` solicitudes al `movies` índice. Si su dominio tiene una política de acceso abierto con control de acceso detallado habilitado, puede dejarlo tal cual: 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/*"
    }
  ]
}
```

------

Como alternativa, puede elegir hacer su política de acceso a dominio más detallada. Por ejemplo, la siguiente política mínima proporciona acceso de lectura a `opensearch-lambda-role` (creado a través de Lambda) al índice `movies`. Para obtener el nombre exacto del rol que Lambda crea automáticamente, vaya a la consola AWS Identity and Access Management (IAM), elija **Roles** y busque «lambda».

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/service-role/opensearch-lambda-role-1abcdefg"
      },
      "Action": "es:ESHttpGet",
      "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/movies/_search"
    }
  ]
}
```

------

**importante**  
Si ha habilitado un control de acceso detallado para el dominio, también debe asignar la [función a un usuario en los](fgac.md#fgac-mapping) OpenSearch paneles; de lo contrario, aparecerán errores de permisos.

### Configure los permisos del rol de ejecución de Lambda
<a name="search-example-lambda-iam"></a>

Además de configurar la política de acceso al dominio, también debe asegurarse de que la función de ejecución de Lambda tenga los permisos de IAM necesarios para acceder a su OpenSearch dominio de servicio. La función Lambda requiere permisos específicos en función de si se utiliza un dominio gestionado o una colección de OpenSearch Service Serverless.

**Para los dominios de OpenSearch servicios gestionados:**

Adjunte la siguiente política de IAM a su función de ejecución de Lambda para que pueda realizar solicitudes a OpenSearch su dominio de servicio:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "es:ESHttpGet",
        "es:ESHttpPost"
      ],
      "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/*"
    }
  ]
}
```

------

**Para las colecciones de OpenSearch Service Serverless:**

Si utiliza OpenSearch Service Serverless, adjunte la siguiente política de IAM a su función de ejecución de Lambda:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "aoss:*",
      "Resource": "arn:aws:aoss:us-west-1:123456789012:collection/collection-id"
    }
  ]
}
```

------

Para adjuntar estas políticas a su rol de ejecución de Lambda:

1. Vaya a la consola de IAM en [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Elija **Funciones** y busque su función de ejecución de Lambda (normalmente denominada `opensearch-lambda-role-xxxxxxxx`).

1. Elija **Agregar permisos** y luego **Crear política insertada**.

1. Elija la pestaña **JSON** y pegue la política correspondiente de arriba, sustituyendo los valores de los marcadores de posición por su recurso real. ARNs

1. Elija **Revisar política**, escriba un nombre como `OpenSearchAccess` y seleccione **Crear política**.

**nota**  
Sin estos permisos de IAM, la función Lambda recibirá errores de «Acceso denegado» al intentar consultar OpenSearch el dominio del servicio, incluso si la política de acceso al dominio permite las solicitudes.

Para obtener más información sobre las políticas de acceso, consulte [Configurar políticas de acceso](createupdatedomains.md#createdomain-configure-access-policies).

## Asigne el rol de Lambda (si utiliza un control de acceso detallado)
<a name="search-example-perms-fgac"></a>

El control de acceso detallado presenta un paso adicional antes de poder probar la aplicación. Incluso si utiliza la autenticación básica HTTP para todos los demás fines, es necesario asignar el rol de Lambda a un usuario, de lo contrario verá errores de permisos.

1. Navegue hasta la URL del OpenSearch panel de control del dominio.

1. En el menú principal, seleccione **Seguridad**, **Roles** y elija el enlace a `all_access`, el rol al que necesita asignar el rol de Lambda.

1. Seleccione **Usuarios asignados**, **Administrar mapeo**. 

1. En **Roles de backend**, agregue el nombre de recurso de Amazon (ARN) del rol de Lambda. El ARN debe adoptar la forma de `arn:aws:iam::123456789123:role/service-role/opensearch-lambda-role-1abcdefg`.

1. Seleccione **Asignar** y confirme que el usuario o el rol aparecen en **Usuarios asignados**.

## Paso 5: Pruebe la aplicación web
<a name="search-example-webpage"></a>

**Para probar la aplicación web**

1. Descargue [sample-site.zip](samples/sample-site.zip), descomprímalo y abra `scripts/search.js` en el editor de texto de su elección.

1. Actualice la variable `apigatewayendpoint` para que apunte al punto de conexión de API Gateway y añada una barra oblicua al final de la ruta en cuestión. Puede encontrar rápidamente el punto de conexión en API Gateway seleccionando **Etapas** y seleccionando el nombre de la API. La variable `apigatewayendpoint` debe adoptar la forma de `https://some-id.execute-api.us-west-1.amazonaws.com/opensearch-api-test`/.

1. Abra `index.html` e intente ejecutar búsquedas de *thor*, *house* y algunos otros términos.  
![\[A continuación se muestra un ejemplo de la búsqueda de thor.\]](http://docs.aws.amazon.com/es_es/opensearch-service/latest/developerguide/images/search-ui.png)

### Solucionar errores de CORS
<a name="search-example-cors"></a>

Aunque la función de Lambda incluye contenido en la respuesta para admitir CORS, es posible que aparezca el siguiente error: 

```
Access to XMLHttpRequest at '<api-gateway-endpoint>' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present in the requested resource.
```

Si esto sucede, pruebe lo siguiente:

1. [Habilitar CORS](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html) en el recurso GET. En **Avanzado**, configure **Access-Control-Allow-Credentials** en `'true'`.

1. Vuelva a implementar su API en API Gateway (**Acciones**, **Implementar API**).

1. Elimine y vuelva a agregar el activador de la función de Lambda. Agregue volver a añadirlo, seleccione **Agregar desencadenador** y cree el punto de conexión HTTP que invoca su función. El desencadenador debe tener la siguiente configuración:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/opensearch-service/latest/developerguide/search-example.html)

## Siguientes pasos
<a name="search-example-next"></a>

Este capítulo es solo un punto de partida para demostrar un concepto. Podría considerar las siguientes modificaciones:
+ Agregue sus propios datos al dominio del OpenSearch servicio.
+ Agregue métodos a su API.
+ En la función de Lambda, modifique la consulta de búsqueda o aumente los diferentes campos.
+ Aplique un estilo diferente a los resultados o modifique `search.js` para mostrar diferentes campos al usuario.