MongoDB和C#:不区分大小写的搜索

时间:2010-12-16 08:56:32

标签: c# .net mongodb mongodb-.net-driver case-insensitive

我正在使用MongoDBC# driver for MongoDB

我最近发现MongoDB中的所有查询都区分大小写。如何进行不区分大小写的搜索?

我找到了一种方法:

Query.Matches(
    "FirstName", 
    BsonRegularExpression.Create(new Regex(searchKey,RegexOptions.IgnoreCase)));

11 个答案:

答案 0 :(得分:61)

最简单,最安全的方法是使用Linq

var names = namesCollection.AsQueryable().Where(name =>
    name.FirstName.ToLower().Contains("hamster"));

tutorial ToLower中所述,ToLowerInvariantToUpperToUpperInvariant都以不区分大小写的方式执行匹配。之后,您可以使用所有受支持的字符串方法,例如ContainsStartsWith

此示例将生成:

{
    "FirstName" : /hamster/is
}

i选项使其不区分大小写。

答案 1 :(得分:37)

我刚刚比其他任何建议都更加简单。但是我意识到由于这个问题的年龄,当时可能还没有这个功能。

使用Bson Regular Expression构造函数的选项传递不区分大小写。我刚看了一下源代码,发现'i'就是你所需要的。例如。

var regexFilter = Regex.Escape(filter);
var bsonRegex = new BsonRegularExpression(regexFilter, "i");

Query.Matches("MyField", bsonRegex);

您不必为了搜索而保留两次记录。

答案 2 :(得分:16)

尝试使用这样的东西:

Query.Matches("FieldName", BsonRegularExpression.Create(new Regex(searchKey, RegexOptions.IgnoreCase)))

答案 3 :(得分:12)

您可能需要将字段存储两次,一次使用其实际值,再次以全小写存储。然后,您可以查询小写版本以进行不区分大小写的搜索(不要忘记同样小写查询字符串)。

这种方法对许多数据库系统起作用(或必要),并且它应该比基于正则表达式的技术(至少对于前缀或精确匹配)表现得更好。

答案 4 :(得分:4)

正如i3arnon回答的那样,您可以使用Queryable进行不区分大小写的比较/搜索。我发现的是,我不能使用string.Equals()方法,因为它不受支持。如果你需要做一个比较,很遗憾,Contains()将不适合让我一直在努力寻求解决方案。

对于想要进行字符串比较的人,只需使用==而不是.Equals()。

代码:

var names = namesCollection.AsQueryable().Where(name =>
    name.FirstName.ToLower() == name.ToLower());

答案 5 :(得分:1)

如果其他人想知道,使用fluent-mongo插件,您可以使用Linq进行查询:

public User FindByEmail(Email email)
{
    return session.GetCollection<User>().AsQueryable()
           .Where(u => u.EmailAddress.ToLower() == email.Address.ToLower()).FirstOrDefault();
}

这导致正确的JS查询。不幸的是,还不支持String.Equals()。

答案 6 :(得分:1)

您还可以使用MongoDB的内置过滤器。它可能会更容易使用mongo的一些方法。

var filter = Builders<Model>.Filter.Where(p => p.PropertyName.ToLower().Contains(s.ToLower()));
var list = collection.Find(filter).Sort(mySort).ToList();

答案 7 :(得分:1)

MongoDB 3.4+ 最简单的方法是使用 ICU 比较级别之一

return await Collection()
.Find(filter, new FindOptions { Collation = new Collation("en", strength: CollationStrength.Primary) })
.ToListAsync();

更多信息https://docs.mongodb.com/manual/reference/method/cursor.collation/index.html

答案 8 :(得分:0)

一种方法是使用MongoDB.Bson.BsonJavaScript类,如下所示

 store.FindAs<Property>(Query.Where(BsonJavaScript.Create(string.Format("this.City.toLowerCase().indexOf('{0}') >= 0", filter.City.ToLower()))));

答案 9 :(得分:0)

对于MongoDB 3.4+,推荐的方法是使用索引。 见https://jira.mongodb.org/browse/DOCS-11105?focusedCommentId=1859745&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-1859745

我通过以下方式成功搜索不区分大小写: 1.使用Collat​​ion为区域设置创建索引(例如:“en”),强度为1或2.有关详细信息,请参阅https://docs.mongodb.com/manual/core/index-case-insensitive/

  1. 在对MongoDb集合执行搜索时使用相同的排序规则。
  2. 举个例子:

    为不区分大小写的

    创建强度为1或2的归类
    private readonly Collation _caseInsensitiveCollation = new Collation("en", strength: CollationStrength.Primary);
    

    创建索引。在我的例子中,我索引了几个字段:

    private void CreateIndex()
    {
        var indexOptions = new CreateIndexOptions {Collation = _caseInsensitiveCollation};
        var indexDefinition
            = Builders<MyDto>.IndexKeys.Combine(
                Builders<MyDto>.IndexKeys.Ascending(x => x.Foo),
                Builders<MyDto>.IndexKeys.Ascending(x => x.Bar));
        _myCollection.Indexes.CreateOne(indexDefinition, indexOptions);
    }
    

    查询时请确保使用相同的排序规则:

    public IEnumerable<MyDto> GetItems()
    {
        var anyFilter = GetQueryFilter();
        var anySort = sortBuilder.Descending(x => x.StartsOn);  
        var findOptions = new FindOptions {Collation = _caseInsensitiveCollation};
    
        var result = _salesFeeRules
            .Find(anyFilter, findOptions)
            .Sort(anySort)
            .ToList();
    
        return result;
    }
    

答案 10 :(得分:-1)

这是精确的文本搜索,不区分大小写(请参见this link)。

{ “FieldName” : /^keywordHere$/i }