【发布时间】:2011-10-29 10:11:33
【问题描述】:
var thename = 'Andrew';
db.collection.find({'name':thename});
如何查询不区分大小写?即使是“andrew”,我也想找到结果;
【问题讨论】:
-
对所有尝试使用涉及正则表达式的答案的人的说明:需要对正则表达式进行清理。
var thename = 'Andrew';
db.collection.find({'name':thename});
如何查询不区分大小写?即使是“andrew”,我也想找到结果;
【问题讨论】:
正则表达式查询将比基于索引的查询慢。
您可以创建具有特定排序规则的索引,如下所示db.collection.createIndex({field:1},{collation: {locale:'en',strength:2}},{background : true});
上述查询将创建一个忽略字符串大小写的索引。需要为每个查询指定排序规则,以便它使用不区分大小写的索引。
查询db.collection.find({field:'value'}).collation({locale:'en',strength:2});
注意 - 如果您没有为每个查询指定排序规则,查询将不会使用新索引。
请参阅此处的 mongodb 文档以获取更多信息 - https://docs.mongodb.com/manual/core/index-case-insensitive/
【讨论】:
这将完美运行db.collection.find({ song_Name: { '$regex': searchParam, $options: 'i' } })
只需添加您的正则表达式 $options: 'i' 其中 i 不区分大小写。
【讨论】:
...在 NodeJS 上使用 mongoose 进行查询:
const countryName = req.params.country;
{ 'country': new RegExp(`^${countryName}$`, 'i') };
或
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
// ^australia$
或
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
// ^turkey$
一个完整的 Javascript 代码示例,NodeJS 和 Mongoose ORM 在 MongoDB 上
// get all customers that given country name
app.get('/customers/country/:countryName', (req, res) => {
//res.send(`Got a GET request at /customer/country/${req.params.countryName}`);
const countryName = req.params.countryName;
// using Regular Expression (case intensitive and equal): ^australia$
// const query = { 'country': new RegExp(`^${countryName}$`, 'i') };
// const query = { 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
const query = { 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
Customer.find(query).sort({ name: 'asc' })
.then(customers => {
res.json(customers);
})
.catch(error => {
// error..
res.send(error.message);
});
});
【讨论】:
使用 Mongoose(和 Node),这很有效:
User.find({ email: /^name@company.com$/i })
User.find({ email: new RegExp(`^${emailVariable}$`, 'i') })
在 MongoDB 中,这很有效:
db.users.find({ email: { $regex: /^name@company.com$/i }})这两行都不区分大小写。数据库中的电子邮件可能是NaMe@CompanY.Com,这两行仍然会在数据库中找到对象。
同样,我们可以使用/^NaMe@CompanY.Com$/i,它仍然会在数据库中找到电子邮件:name@company.com。
【讨论】:
User.find({ email: new RegExp(^${emailVariable}$, 'i') }) 示例
要查找不区分大小写的字符串,请使用这个,
var thename = "Andrew";
db.collection.find({"name":/^thename$/i})
【讨论】:
一种简单的方法是使用 $toLower,如下所示。
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])
【讨论】:
您可以使用不区分大小写的索引:
以下示例创建一个没有默认排序规则的集合,然后使用不区分大小写的排序规则在名称字段上添加索引。 International Components for 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 } } )
要使用索引,查询必须指定相同的排序规则。
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 } )
或者您可以使用默认排序规则创建一个集合:
db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
【讨论】:
要查找不区分大小写的文字字符串:
db.collection.find({
name: {
$regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
}
});
db.collection.find({
name_lower: name.toLowerCase()
});
正则表达式比文字字符串匹配慢。但是,额外的小写字段会增加您的代码复杂性。如有疑问,请使用正则表达式。如果它可以替换您的字段,我建议仅使用明确的小写字段,也就是说,您首先不关心大小写。
请注意,您需要在正则表达式之前对名称进行转义。如果您想要用户输入通配符,最好在转义后附加.replace(/%/g, '.*'),以便匹配“a%”以查找所有以“a”开头的名称。
【讨论】:
您需要为此使用不区分大小写的regular expression,例如
db.collection.find( { "name" : { $regex : /Andrew/i } } );
要使用thename 变量中的正则表达式模式,请构造一个新的RegExp 对象:
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
更新:对于完全匹配,您应该使用正则表达式 "name": /^Andrew$/i。感谢 Yannick L。
【讨论】:
name 的文档,而不仅仅是等于。
{ "name": /^Andrew$/i }
MongoDB 3.4 现在包含创建真正不区分大小写索引的功能,这将大大提高在大型数据集上不区分大小写查找的速度。它是通过指定强度为 2 的排序规则生成的。
可能最简单的方法是在数据库上设置排序规则。然后所有查询都会继承该排序规则并使用它:
db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation
你也可以这样做:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
并像这样使用它:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
这将返回名为“new york”、“New York”、“New york”等的城市。
【讨论】:
以下查询将查找具有所需字符串的文档不敏感且全局出现
db.collection.find({name:{
$regex: new RegExp(thename, "ig")
}
},function(err, doc) {
//Your code here...
});
【讨论】:
我已经这样解决了。
var thename = 'Andrew';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
如果你想查询“不区分大小写的精确匹配”,那么你可以这样。
var thename = '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
【讨论】:
我几个小时前刚刚解决了这个问题。
var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });
您甚至可以通过从 Andrew 的用户对象中选择您需要的字段来扩展此功能:
db.collection.find({ $text: { $search: thename } }).select('age height weight');
参考:https://docs.mongodb.org/manual/reference/operator/query/text/#text
【讨论】:
Chris Fulstow 的解决方案可行 (+1),但它可能效率不高,尤其是在您的收藏非常大的情况下。无根正则表达式(那些不以^ 开头的正则表达式,它将正则表达式锚定到字符串的开头),以及那些使用i 标志以区分大小写的正则表达式将不会使用索引,即使它们存在。
您可能考虑的另一种选择是将数据非规范化以存储name 字段的小写版本,例如name_lower。然后,您可以有效地查询(特别是如果它被索引)不区分大小写的完全匹配,例如:
db.collection.find({"name_lower": thename.toLowerCase()})
或者与前缀匹配(一个有根的正则表达式)为:
db.collection.find( {"name_lower":
{ $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);
这两个查询都将使用name_lower 上的索引。
【讨论】:
new RegExp('^'+ username + '$', "i") 以完全匹配。
".*"。