Ejemplo:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
fuente
Ejemplo:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
Podrías usar una expresión regular .
En su ejemplo eso 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 un costo adicional cada vez que lo encuentre. Obviamente, esto no funcionará para los nombres de personas y tal, pero tal vez los casos de uso como etiquetas.
ACTUALIZAR:
La respuesta original ahora es obsoleta. Mongodb ahora admite la búsqueda avanzada de texto completo, con muchas funciones.
RESPUESTA ORIGINAL:
Cabe señalar que la búsqueda con mayúsculas y minúsculas de regex / i significa que mongodb no puede buscar por índice, por lo que las consultas contra grandes conjuntos de datos pueden llevar mucho tiempo.
Incluso con conjuntos de datos pequeños, no es muy eficiente. Obtiene un éxito de CPU mucho mayor que el que garantiza su consulta, lo que podría convertirse en un problema si está tratando de alcanzar la escala.
Como alternativa, puede almacenar una copia en mayúscula y buscar contra eso. Por ejemplo, tengo una tabla de usuario que tiene un nombre de usuario con mayúsculas y minúsculas, pero la identificación es una copia en mayúscula del nombre de usuario. Esto garantiza que la duplicación entre mayúsculas y minúsculas sea imposible (no se permitirá tener "Foo" y "foo"), y puedo buscar por id = username.toUpperCase () para obtener una búsqueda que no distinga entre mayúsculas y minúsculas para el nombre de usuario.
Si su campo es grande, como un cuerpo de mensaje, duplicar datos probablemente no sea una buena opción. Creo que usar un indexador extraño como Apache Lucene es la mejor opción en ese caso.
username: 'bill'
coincide BILL
o Bill
no una consulta de búsqueda de texto completo, que también coincidiría con palabras derivadas de bill
, como Bills
, billed
etc.
Si necesita crear la expresión regular a partir de una variable, esta es una forma mucho mejor de hacerlo: https://stackoverflow.com/a/10728069/309514
Luego puedes hacer algo como:
var string = "SomeStringToFind";
var regex = new RegExp(["^", string, "$"].join(""), "i");
// Creates a regex of: /^SomeStringToFind$/i
db.stuff.find( { foo: regex } );
Esto tiene el beneficio de ser más programático o puede obtener un aumento de rendimiento compilándolo con anticipación si lo está reutilizando mucho.
new RegExp("^" + req.params.term.toLowerCase(), "i")
también funciona bien
Tenga en cuenta que el ejemplo anterior:
db.stuff.find( { foo: /bar/i } );
hará que todas las entradas que contengan barra coincidan con la consulta (bar1, barxyz, barra libre), podría ser muy peligroso para una búsqueda de nombre de usuario en una función de autenticación ...
Es posible que deba hacer que coincida solo con el término de búsqueda utilizando la sintaxis de expresión regular apropiada como:
db.stuff.find( { foo: /^bar$/i } );
Consulte http://www.regular-expressions.info/ para obtener ayuda sobre la sintaxis de las expresiones regulares.
Comenzando con 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 de detección de mayúsculas y minúsculas .
Personalmente le envié un correo electrónico a uno de los fundadores para que funcionara, ¡y él lo hizo posible! Era un problema en JIRA desde 2009 , y muchos han solicitado la función. Así es como funciona:
Se crea un índice que no distingue mayúsculas de minúsculas especificando una colación con una intensidad de 1 o 2. Puede crear un índice que no distinga mayúsculas de minúsculas como este:
db.cities.createIndex(
{ city: 1 },
{
collation: {
locale: 'en',
strength: 2
}
}
);
También puede especificar una clasificación predeterminada por colección cuando los 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 clasificación en la 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.
Las respuestas que sugieren utilizar la búsqueda de texto completo son incorrectas en este caso (y potencialmente peligrosas ). La pregunta era hacer una consulta que no distinga entre mayúsculas y minúsculas, por ejemplo, username: 'bill'
coincidencia BILL
o Bill
no una consulta de búsqueda de texto completo, que también coincidiría con palabras derivadas de bill
, como Bills
, billed
etc.
Las respuestas que sugieren usar expresiones regulares son lentas, porque incluso con índices, la documentación dice :
"Las consultas de expresión regular 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 inyección de entrada del usuario .
db.zipcodes.find({city : "NEW YORK"}); // Case-sensitive
db.zipcodes.find({city : /NEW york/i}); // Note the 'i' flag for case-insensitivity
TL; DR
No use RegExp
Vuélvase natural y use la indexación incorporada de mongodb, busque
db.articles.insert(
[
{ _id: 1, subject: "coffee", author: "xyz", views: 50 },
{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 },
{ _id: 4, subject: "baking", author: "xyz", views: 100 },
{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
{ _id: 6, subject: "Сырники", author: "jkl", views: 80 },
{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
]
)
Necesita crear un índice en cualquier campo de TEXTO que desee buscar, sin que la consulta de indexación sea extremadamente lenta
db.articles.createIndex( { subject: "text" } )
db.articles.find( { $text: { $search: "coffee",$caseSensitive :true } } ) //FOR SENSITIVITY
db.articles.find( { $text: { $search: "coffee",$caseSensitive :false } } ) //FOR INSENSITIVITY
username: 'bill'
coincide BILL
o Bill
no una consulta de búsqueda de texto completo, que también coincidiría con palabras derivadas de bill
, como Bills
, billed
etc.
db.company_profile.find({ "companyName" : { "$regex" : "Nilesh" , "$options" : "i"}});
$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);
Mongo (versión actual 2.0.0) no permite búsquedas sin distinción entre mayúsculas y minúsculas en campos indexados; consulte su documentación . Para los campos no indexados, las expresiones regulares enumeradas en las otras respuestas deberían estar bien.
Una cosa muy importante a tener en cuenta al usar una consulta basada en Regex: cuando esté haciendo esto para un sistema de inicio de sesión, escape de todos los caracteres que está buscando y no olvide los operadores ^ y $. Lodash tiene una buena función para esto , si ya lo está usando:
db.stuff.find({$regex: new RegExp(_.escapeRegExp(bar), $options: 'i'})
¿Por qué? Imagine que un usuario ingresa .*
como su nombre de usuario. Eso coincidiría con todos los nombres de usuario, permitiendo un inicio de sesión simplemente adivinando la contraseña de cualquier usuario.
El mejor método está en el idioma que elija, cuando cree un contenedor de modelo para sus objetos, haga que su método save () repita un conjunto de campos en los que buscará que también están indexados; ese conjunto de campos debe tener contrapartidas en minúsculas que luego se utilizan para la búsqueda.
Cada vez que el objeto se guarda nuevamente, las propiedades en minúsculas se verifican y actualizan con cualquier cambio en las propiedades principales. Esto hará que pueda buscar de manera eficiente, pero oculte el trabajo adicional necesario para actualizar los campos lc cada vez.
Los campos en minúsculas podrían ser una clave: valor de almacén de objetos o simplemente el nombre del campo con un prefijo lc_. Utilizo el segundo para simplificar las consultas (las consultas de objetos profundos pueden ser confusas a veces).
Nota: desea indexar los campos lc_, no los campos principales en los que se basan.
Supongamos que desea buscar "columna" en "Tabla" y desea una búsqueda que no distinga entre mayúsculas y minúsculas. La mejor y más eficiente forma es la siguiente;
//create empty JSON Object
mycolumn = {};
//check if column has valid value
if(column) {
mycolumn.column = {$regex: new RegExp(column), $options: "i"};
}
Table.find(mycolumn);
El código anterior simplemente agrega su valor de búsqueda como RegEx y busca con criterios insensibles establecidos con "i" como opción.
Todo lo mejor.
Usando Mongoose esto funcionó para mí:
var find = function(username, next){
User.find({'username': {$regex: new RegExp('^' + username, 'i')}}, function(err, res){
if(err) throw err;
next(null, res);
});
}
.toLowerCase()
redundante si especificas el distintivo de mayúsculas y minúsculas de i
?
El marco de agregación se introdujo en mongodb 2.2. Puede usar el operador de cadena "$ strcasecmp" para hacer una comparación entre cadenas sin distinción entre mayúsculas y minúsculas. Es más recomendable y más fácil que usar regex.
Aquí está el documento oficial sobre el operador de comando de agregación: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .
Puede usar índices sin distinción entre mayúsculas y minúsculas :
El siguiente ejemplo crea una colección sin clasificación predeterminada, luego agrega un índice en el campo de nombre con una clasificación que no distingue entre mayúsculas y minúsculas. Componentes internacionales para Unicode
/* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )
Para usar el índice, las consultas deben especificar la misma clasificación.
db.users.insert( [ { name: "Oğuz" },
{ name: "oğuz" },
{ name: "OĞUZ" } ] )
// does not use index, finds one result
db.users.find( { name: "oğuz" } )
// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )
// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )
o puede crear una colección con clasificación predeterminada:
db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
Para buscar una variable y escapar de ella:
const escapeStringRegexp = require('escape-string-regexp')
const name = 'foo'
db.stuff.find({name: new RegExp('^' + escapeStringRegexp(name) + '$', 'i')})
Escapar de la variable protege la consulta contra ataques con '. *' U otra expresión regular.
Use RegExp , en caso de que alguna otra opción no funcione para usted, RegExp es una buena opción. Hace que la cadena no sea sensible.
var username = new RegExp("^" + "John" + "$", "i");;
use el nombre de usuario en las consultas, y luego está hecho.
Espero que funcione para ti también. Todo lo mejor.
He creado un Func simple para la expresión regular sin distinción entre mayúsculas y minúsculas, que uso en mi filtro.
private Func<string, BsonRegularExpression> CaseInsensitiveCompare = (field) =>
BsonRegularExpression.Create(new Regex(field, RegexOptions.IgnoreCase));
Luego, simplemente filtre en un campo de la siguiente manera.
db.stuff.find({"foo": CaseInsensitiveCompare("bar")}).count();
Usar un filtro me funciona en C #.
string s = "searchTerm";
var filter = Builders<Model>.Filter.Where(p => p.Title.ToLower().Contains(s.ToLower()));
var listSorted = collection.Find(filter).ToList();
var list = collection.Find(filter).ToList();
Incluso puede usar el índice porque creo que los métodos se invocan después de la devolución, pero aún no lo he probado.
Esto también evita un problema de
var filter = Builders<Model>.Filter.Eq(p => p.Title.ToLower(), s.ToLower());
ese mongodb pensará que p.Title.ToLower () es una propiedad y no se asignará correctamente.
Para cualquiera que use Golang y desee tener una búsqueda de texto completo entre mayúsculas y minúsculas con mongodb y la biblioteca de mgo godoc globalsign .
collation := &mgo.Collation{
Locale: "en",
Strength: 2,
}
err := collection.Find(query).Collation(collation)
Como puede ver en mongo docs, ya que el $text
índice de la versión 3.2 no distingue entre mayúsculas y minúsculas por defecto: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivity
Cree un índice de texto y use el operador $ text en su consulta .
username: 'bill'
coincide BILL
o Bill
no una consulta de búsqueda de texto completo, que también coincidiría con palabras derivadas de bill
, como Bills
, billed
etc.
Estos han sido probados para búsquedas de cadenas
{'_id': /.*CM.*/} ||find _id where _id contains ->CM
{'_id': /^CM/} ||find _id where _id starts ->CM
{'_id': /CM$/} ||find _id where _id ends ->CM
{'_id': /.*UcM075237.*/i} ||find _id where _id contains ->UcM075237, ignore upper/lower case
{'_id': /^UcM075237/i} ||find _id where _id starts ->UcM075237, ignore upper/lower case
{'_id': /UcM075237$/i} ||find _id where _id ends ->UcM075237, ignore upper/lower case
Me enfrenté a un problema similar y esto es lo que funcionó para mí:
const flavorExists = await Flavors.findOne({
'flavor.name': { $regex: flavorName, $options: 'i' },
});
$regex
y $options
. ¿Qué hiciste Ctrl + F?
$regex
es ineficiente y potencialmente inseguro, como he explicado en mi edición a esta otra respuesta de 2016 . ¡No hay vergüenza en eliminar respuestas si ya no sirven a la comunidad!
$caseSensitive: false
. Ver: docs.mongodb.org/manual/reference/operator/query/text/…$caseSensitive
ya es falso de forma predeterminada, y eso no responde a la pregunta, porque solo funciona en campos indexados. OP estaba buscando una comparación de cadenas que no distinga entre mayúsculas y minúsculas.