Saltar al contenido

MongoDB: ¿Es posible hacer una consulta que no distinga entre mayúsculas y minúsculas?

Haz todo lo posible por comprender el código bien antes de utilizarlo a tu trabajo si tquieres aportar algo puedes compartirlo con nosotros.

Solución:

Podrías usar una expresión regular.

En tu ejemplo sería:

db.stuff.find(  foo: /^bar$/i  );

Sin embargo, debo decir que tal vez podría reducir (o aumentar) el valor en el camino en lugar de incurrir en el costo adicional cada vez que lo encuentra. Obviamente, esto no funcionará para los nombres de las personas y demás, pero tal vez casos de uso como etiquetas.

ACTUALIZAR:

La respuesta original ahora está obsoleta. Mongodb ahora admite la búsqueda avanzada de texto completo, con muchas funciones.

RESPUESTA ORIGINALES:

Debe tenerse en cuenta que la búsqueda con /i insensible a mayúsculas y minúsculas de expresiones regulares significa que mongodb no puede buscar por índice, por lo que las consultas en grandes conjuntos de datos pueden llevar mucho tiempo.

Incluso con pequeños conjuntos de datos, no es muy eficiente. Recibe un golpe de CPU mucho mayor de lo que justifica su consulta, lo que podría convertirse en un problema si está tratando de lograr escala.

Como alternativa, puede almacenar una copia en mayúsculas y buscar en ella. Por ejemplo, tengo una tabla de Usuario que tiene un nombre de usuario que es mixed caso, pero la identificación es una copia en mayúsculas del nombre de usuario. Esto garantiza que la duplicación que distingue entre mayúsculas y minúsculas sea imposible (no se permitirá tener tanto “Foo” como “foo”), y puedo buscar por id = nombre de usuario.toUpperCase() para obtener una búsqueda de nombre de usuario que no distinga entre mayúsculas y minúsculas.

Si su campo es grande, como el cuerpo de un mensaje, probablemente la duplicación de datos no sea una buena opción. Creo que usar un indexador extraño como Apache Lucene es la mejor opción en ese caso.

A partir de MongoDB 3.4, la forma recomendada de realizar búsquedas rápidas que no distinguen entre mayúsculas y minúsculas es utilizar un Índice insensible a mayúsculas y minúsculas.

Personalmente, le envié un correo electrónico a uno de los fundadores para que hiciera que esto funcionara, ¡y lo hizo posible! Fue un problema en JIRA desde 2009 y muchos han solicitado la función. Así es como funciona:

Un índice que no distingue entre mayúsculas y minúsculas se crea especificando una intercalación con una fuerza de 1 o 2. Puede crear un índice que no distingue entre mayúsculas y minúsculas como este:

db.cities.createIndex(
   city: 1 ,
   
    collation: 
      locale: 'en',
      strength: 2
    
  
);

También puede especificar una intercalación predeterminada por colección cuando las crea:

db.createCollection('cities',  collation:  locale: 'en', strength: 2   );

En cualquier caso, para utilizar el índice que no distingue entre mayúsculas y minúsculas, debe especificar la misma intercalación en el find operación que se utilizó al crear el índice o la colección:

db.cities.find(
   city: 'new york' 
).collation(
   locale: 'en', strength: 2 
);

Esto devolverá “Nueva York”, “nueva york”, “Nueva york”, etc.

Otras notas

  • Las respuestas que sugieren utilizar la búsqueda de texto completo es incorrecta en este caso (y potencialmente peligroso). La pregunta era sobre hacer una consulta que no distinga entre mayúsculas y minúsculas, por ejemplo username: 'bill' pareo BILL o Billno una consulta de búsqueda de texto completo, que también coincidiría con palabras derivadas de billcomo Bills, billed etc.

  • Las respuestas que sugieren usar expresiones regulares son lentas, porque incluso con índices, la documentación dice:

    “Las consultas de expresiones regulares que no distinguen entre mayúsculas y minúsculas generalmente no pueden usar índices de manera efectiva. La implementación de $regex no reconoce la intercalación y no puede utilizar índices que no distinguen entre mayúsculas y minúsculas”.

    $regex las respuestas también corren el riesgo de la inyección de entrada del usuario.

Si te ha sido de utilidad nuestro post, te agradeceríamos que lo compartas con otros seniors y nos ayudes a extender nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *