MongoDB y el operador LIKE: La solución obvia no es la mejor

Muchos desarrolladores buscan el equivalente al `LIKE` de SQL en MongoDB y optan por una solución que, aunque funciona, suele ser un exceso de ingeniería. Te muestro cómo simplificar.

MongoDB y el “LIKE” de SQL: ¿Necesitas realmente complicarte?

Cuando uno viene de un mundo de bases de datos relacionales, buscar texto que contenga una subcadena es pan de cada día. En SQL, usamos LIKE '%patron%'. La traducción directa a MongoDB que mucha gente usa, y que de hecho yo mismo usé al principio, es con expresiones regulares que incluyen .* al principio y al final.

Es común ver algo así en muchos proyectos, o que me pregunten por ello:

db.users.find({"name": /.*patron.*/})

Esta solución funciona, claro. Pero aquí va mi opinión: casi siempre es sobreingeniería. Si solo necesitas saber si un string contiene un patrón, el .* inicial y final son completamente redundantes. MongoDB, por defecto, ya busca el patrón en cualquier parte de la cadena.

La simplicidad que funciona

Para la gran mayoría de los casos donde buscarías un LIKE '%patron%' en SQL, la versión más simple y directa en MongoDB es esta:

db.users.find({"name": /patron/})

Ambas consultas hacen exactamente lo mismo si tu objetivo es solo verificar si la cadena name contiene la palabra "patron" en algún lugar. La diferencia es que la segunda es más clara, más concisa y no añade complejidad innecesaria. Ojo que la legibilidad importa.

Me frustra ver regex más complejos de lo necesario. Las soluciones simples que funcionan son siempre las mejores. A veces, por intentar replicar SQL al pie de la letra, terminamos complicando lo que no es.

¿Cuándo sí usar .* o anclajes?

Las expresiones regulares son poderosas, y sí tienen su lugar. Si necesitas anclar tu búsqueda, ahí sí son esenciales:

  • Para buscar strings que empiecen con "patron": /^patron.*/ o simplemente /^patron/
  • Para buscar strings que terminen con "patron": /.*patron$/ o simplemente /patron$/
  • Y claro, para patrones más complejos que el simple "contiene" o "empieza/termina con".

Pero para un "contiene" genérico, no te compliques.

Me costó entender que los regex de MongoDB no son una traducción 1:1 de LIKE y que tienen su propia lógica para la búsqueda de subcadenas. Ojalá hubiera sabido antes que la simplicidad en este caso no solo es más elegante, sino a menudo más eficiente para el motor de la base de datos y, por cierto, para quien lee el código después.

Jorge RequenaDeveloper full-stack · Chile