Ahí van algunos consejos para los que trabajen con Google App Engine y estén interesados en hacer búsquedas en el datastore que incluyan búsquedas totales o parciales de texto en campos.

Para aquellos que hemos trabajado con bases de datos relacionales, puede costar un poco cambiar el chip cuando se trabajan con sentencias usando GQL. ¿Que podemos hacer si queremos el clásico elemento de SQL "LIKE" para hacer una búsqueda parcial de un texto?, nos encontraremos que GQL no permite ese tipo de sentencias, por la eficiencia y la escalabilidad del sistema (que es lo más prioritario en GAE).

Aunque hay librerías para realizar búsquedas (no las he probado, así que poco puedo decir), vayamos por algo simple, sin librerías ni pifostios.

Hacer búsquedas de registros cuyo campo A empiece por "XXX".

Entidad: Clientes

Campo: Nombre

Empieza por: "Jua"

query = db.Query(Clientes)
query.filter('nombre >=', 'Jua').filter('nombre <', 'Jua' + u'ufffd')

El valor u'ufffd' es como decir "el elemento unicode más grande que existe", en definitiva hacemos algo así como: "Búscame todos los registros de clientes cuyo nombre esté entre 'Jua' y 'JuaINFINITO' (o casi) "

En el caso que queramos hacer búsquedas de la forma "registros cuyo campo termine en"... la cosa está más complicada. Para ello habría que crearse un campo especial en el datastore que almacene el string a buscar volteado... y realizar la misma sentencia más arriba descrita.

Para realizar búsquedas de textos que coincidan exactamente la cosa es más simple, con usar "=" en nuestras queries.

query = db.Query(Clientes)
query.filter('nombre =', 'Juan').

Hint! OJO! Que si ponemos 'nombre=' posiblemente no nos aparezca ningún resultado. Dejad un espacio entre el campo a buscar y el operador.

Otra cosa a tener en cuenta a la hora de almacenar la información en el datastore, es la siguiente:

¿Queremos realizar búsquedas que no sean case-sensitive? En ese caso es recomendable que los campos guardados sean todos lowercase o uppercase. De esta forma, nos aseguramos que si buscamos registros que empiecen por las letras "jua" o "Jua" nos devolverán los mismos resultados. La variable de búsqueda puede ser tratada en python (o java) para convertirla a mayúsculas o minúsculas completamente antes de compararla con la información del datastore.

En el caso que ya tengamos la información almacenada tal y como llegan de los formularios/sincronizaciones/dondesea podemos hacer dos cosas:

  • Convertir todos esos textos a mayúsculas/minúsculas dentro del datastore y luego tener en cuenta a nivel de programación que dichos campos están en mayúscula/minúscula y su presentación requiera otro formato.
  • Crear nuevos campos alternativos donde se guarden copias de los campos a buscar en el formato que queramos:  name = "Juan"   name_search ="juan" y haremos las búsquedas tomando como referencia "name_search", aunque mostremos en la UI el campo "name".

Para hacer estas dos últimas tareas tenemos la herramienta mapreduce que nos puede ayudar enormemente a la hora de modificar el datastore y su información "dinámicamente", pero de esto, se hablará en otro post.

Todo esto está basado en la experiencia que poco a poco vamos adquiriendo en GAE, es posible que haya formas más eficientes y mejor de hacer las cosas. Siempre es bueno escuchar otras opiniones.