regex - similar - ¿Cómo realizo consultas insensibles a mayúsculas/minúsculas en Mongodb?
regex robomongo (9)
Acabo de resolver este problema hace unas horas.
var thename = ''Andrew''
db.collection.find({ $text: { $search: thename } });
- La sensibilidad de caso y la sensibilidad diacrítica se establecen en falso de forma predeterminada cuando se realizan consultas de esta manera.
Incluso puede ampliar esto al seleccionar en los campos que necesita del objeto de usuario de Andrew de esta manera:
db.collection.find({ $text: { $search: thename } }).select(''age height weight'');
Referencia: https://docs.mongodb.org/manual/reference/operator/query/text/#text
var thename = ''Andrew'';
db.collection.find({''name'':thename});
¿Cómo consulto mayúsculas y minúsculas? Quiero encontrar el resultado incluso si "andrew";
La siguiente consulta encontrará los documentos con la cadena requerida de forma insensible y con ocurrencia global también
db.collection.find({name:{
$regex: new RegExp(thename, "ig")
}
},function(err, doc) {
//Your code here...
});
La solución de Chris Fulstow funcionará (+1), sin embargo, puede no ser eficiente, especialmente si su colección es muy grande. Las expresiones regulares no enraizadas (aquellas que no comienzan con ^
, que ancla la expresión regular al comienzo de la cadena), y las que usan la marca i
para la distinción de mayúsculas y minúsculas no usarán índices, incluso si existen.
Una opción alternativa que podría considerar es desnormalizar sus datos para almacenar una versión en minúsculas del campo de name
, por ejemplo, name_lower
. A continuación, puede consultarlo de manera eficiente (especialmente si está indexado) para las coincidencias exactas que no distinguen entre mayúsculas y minúsculas, como:
db.collection.find({"name_lower": thename.toLowerCase()})
O con una coincidencia de prefijo (una expresión regular enraizada) como:
db.collection.find( {"name_lower":
{ $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);
Ambas consultas usarán un índice en name_lower
.
Lo he resuelto así.
var thename = ''Andrew'';
db.collection.find({''name'': {''$regex'': thename,$options:''i''}});
Si desea consultar sobre ''emparejamiento exacto insensible a mayúsculas / minúsculas'', puede seguir así.
var thename = ''^Andrew$'';
db.collection.find({''name'': {''$regex'': thename,$options:''i''}});
MongoDB 3.4 ahora incluye la capacidad de hacer un verdadero índice insensible a las mayúsculas y minúsculas, lo que aumentará drásticamente la velocidad de búsquedas insensibles a mayúsculas y minúsculas en grandes conjuntos de datos. Se realiza al especificar una intercalación con una fuerza de 2.
Probablemente la forma más fácil de hacerlo es establecer una intercalación en la base de datos. Entonces todas las consultas heredan esa intercalación y la usarán:
db.createCollection("cities", { collation: { locale: ''en_US'', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation
También puedes hacerlo así:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
Y úsalo así:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
Esto devolverá las ciudades llamadas "Nueva York", "Nueva York", "Nueva York", etc.
Para más información: https://jira.mongodb.org/browse/SERVER-90
Para buscar cadenas de literales insensibles a mayúsculas y minúsculas:
Uso de expresiones regulares (recomendado)
db.collection.find({
name: {
$regex: new RegExp(''^'' + name.replace(/[-////^$*+?.()|[/]{}]/g, ''//$&'') + ''$'', ''i'')
}
});
Usar el índice de minúsculas (más rápido)
db.collection.find({
name_lower: name.toLowerCase()
});
Las expresiones regulares son más lentas que la coincidencia literal de cadenas. Sin embargo, un campo minúsculo adicional aumentará la complejidad de su código. En caso de duda, use expresiones regulares. Sugeriría usar solo un campo explícitamente minúsculo si puede reemplazar tu campo, es decir, no te importa el caso en primer lugar.
Tenga en cuenta que deberá escapar del nombre antes de regex. Si desea .replace(/%/g, ''.*'')
comodines de entrada de usuario, prefiera .replace(/%/g, ''.*'')
Después de escapar, de modo que pueda hacer coincidir "a%" para buscar todos los nombres que comiencen por ''a''.
Puede usar Índices insensibles a mayúsculas y minúsculas :
El siguiente ejemplo crea una colección sin intercalación predeterminada, luego agrega un índice en el campo de nombre con una intercalación insensible a 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 intercalació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 colación predeterminada:
db.createCollection("users", { collation: { locale: ''tr'', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
Tendría que usar una expresión regular insensible a mayúsculas / minúsculas para esta, por ejemplo
db.collection.find( { "name" : { $regex : /Andrew/i } } );
Para usar el patrón de thename
regulares de su variable nombre, construya un nuevo objeto RegExp :
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
Actualización: para una coincidencia exacta, debe usar el "name": /^Andrew$/i
expresiones regulares "name": /^Andrew$/i
. Gracias a Yannick L.
Una manera fácil sería usar $ toLower como a continuación.
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])