En este documento se describen las prácticas recomendadas para la API Search. Usamos comillas simples ('') para delimitar las cadenas de consulta. De esta forma, una consulta que contenga frases de varias palabras entre comillas dobles se puede delimitar sin confusiones:
'field:"some text" some-value'
.
Llamadas a Index.put() e Index.delete() en lote
Puedes transferir hasta 200 documentos a la vez al añadirlos o eliminarlos de un índice. Es mucho más eficiente que gestionarlas una a una.
Usar la clasificación de documentos para preordenar documentos
De forma predeterminada, la búsqueda devuelve los resultados ordenados de mayor a menor. Además, de forma predeterminada, la API Search asigna a cada documento el número de segundos transcurridos desde el 1 de enero del 2011. De esta forma, se devuelven primero los documentos más recientes. Sin embargo, si no necesitas que los documentos se ordenen por el momento en que se añadieron, puedes usar el rango para otros fines. Supongamos que tienes una aplicación inmobiliaria. Lo que más quieren los clientes es ordenar por precio. Para que la ordenación predeterminada sea eficiente, puedes asignar el rango al precio de la casa.
Si necesitas varios criterios de ordenación, como el precio de menor a mayor y de mayor a menor, puedes crear un índice independiente para cada criterio. Un índice tendría el valor de rango = precio y el otro, rango = MAXINT - precio (ya que el rango debe ser positivo).
Usar el rango como clave de ordenación mejorará el rendimiento de la búsqueda. Para especificar otras claves de ordenación, debe usar opciones de ordenación, lo que limita el número de resultados de búsqueda a 10.000 documentos. En este caso, el orden determinado por la clasificación determinará qué documentos se incluirán en la ordenación. Consulta más información sobre las opciones de ordenación.
Usar campos atom para datos booleanos
Almacenar datos booleanos en campos numéricos es muy ineficiente. Usa campos de tipo atómico y asigna tus constantes favoritas (True/False, yes/no, 0/1).
Convierte lo negativo en positivo
Supongamos que tienes un término especial para identificar los restaurantes cuya cocina no está definida. Si quieres excluir esos restaurantes, puedes usar 'NOT cuisine:undefined'
como consulta. Sin embargo, es más caro de evaluar (tanto en operaciones facturables como en tiempo de computación) que buscar restaurantes cuya cocina se conoce. En lugar de tener un campo de cocina, puedes usar dos: cuisine
y cuisine_known
. Este último es un campo de átomo. En el caso de los restaurantes en los que se define la cocina, debe asignar al primer campo el tipo de cocina y al segundo, el valor "yes"
. En el caso de los restaurantes cuya cocina no conozcas, asigna el valor ""
(una cadena vacía) a cuisine y el valor "no"
a cuisine_known
. Ahora, para encontrar restaurantes conocidos por su cocina, puedes hacer una consulta 'cuisine_known:yes'
, que es mucho más rápida que la negación.
Convierte las disyunciones en conjunciones
La disyunción "OR" es una operación costosa tanto en operaciones facturables como en tiempo de computación. Supongamos que quieres buscar 'cuisine:Japanese OR cuisine:Korean'
. Otra opción es indexar los documentos con categorías de cocina más generales. En este caso, la consulta se puede simplificar a 'cuisine:Asian'
.
Eliminar tautologías de las consultas
Supongamos que quieres encontrar todos los restaurantes de Madrid. Si tus documentos solo tienen un campo llamado "city", al usar la consulta 'city:toronto AND NOT city:montreal'
obtendrás los mismos resultados que con 'city:toronto'
, ya que si la ciudad es "toronto"
, no puede ser "montreal"
. La segunda consulta se ejecuta mucho más rápido, ya que solo incluye un término. La primera consulta realiza tres pasos: primero, busca una lista de documentos en los que la ciudad sea "toronto"; después, busca una lista de todas las ciudades en las que la ciudad no sea "montreal"; y, por último, calcula la intersección de las dos listas.
Acotar el intervalo antes de ordenar
Supongamos que tu aplicación almacena información sobre restaurantes de todo el mundo y quieres mostrar los más cercanos al usuario actual. Una forma de hacerlo es ordenar los documentos coincidentes por la distancia a la ubicación del usuario. Sin embargo, si tienes 1.000.000 de restaurantes, ejecutar una consulta como 'cuisine:japanese'
con la expresión de ordenación distance(geopoint(x, y), restaurant_loc) llevará mucho tiempo. Es recomendable añadir filtros a una consulta para empezar con un conjunto de documentos seleccionados más destacado que ordenar. Una solución es crear categorías geográficas, como país, estado y ciudad. Podrías deducir la ciudad y el estado a partir de la ubicación del usuario. Tu consulta se convierte en 'cuisine:japanese AND city:<user-city>'
. Es muy probable que ya no tengas que ordenar 1.000.000 de documentos.
Usa categorías específicas para evitar o minimizar la ordenación
Si usas la clasificación para ordenar los restaurantes por precio, puedes crear un campo price_range
que contenga categorías de precios: price_0_10
, price_11_20
, price_21_30
, price_31_40
y price_41_lots
. Después, podrías encontrar todos los restaurantes que cuestan entre 21 $y 40 $sin ordenar los resultados con la consulta 'price_range:price_21_30 OR price_range:price_31_40'
. En muchos casos, las categorías adecuadas no son tan claras, pero con esta técnica puede rechazar un gran número de documentos antes de acotar la búsqueda con consultas costosas, como '... AND price>25 AND price<35'
.
No puntúes las coincidencias a menos que sea necesario
La puntuación se usa para indicar el grado de coincidencia de un documento con una consulta. Sin embargo, a menos que quieras ordenar los resultados por puntuación, no solicites la puntuación. Solo ralentizará tu búsqueda.