wake-up-neo.com

MongoDB und C #: Suche ohne Berücksichtigung der Groß- und Kleinschreibung

Ich benutze MongoDB und den C # -Treiber für MongoDB .

Ich habe kürzlich festgestellt, dass bei allen Abfragen in MongoDB die Groß- und Kleinschreibung beachtet wird. Wie kann ich eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen?

Ich habe einen Weg gefunden, dies zu tun: 

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

Die einfachste und sicherste Methode ist die Verwendung von Linq:

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

Wie im Tutorial erklärtToLower, führen ToLowerInvariant, ToUpper und ToUpperInvariant alle Übereinstimmungen mit einer Groß-/Kleinschreibung durch. Danach können Sie alle unterstützten String-Methoden wie Contains oder StartsWith verwenden.

Dieses Beispiel erzeugt Folgendes:

{
    "FirstName" : /hamster/is
}

Mit der Option i wird die Groß- und Kleinschreibung nicht berücksichtigt.

56
i3arnon

Ich habe das jetzt viel einfacher umgesetzt als alle anderen Vorschläge. Aufgrund des Alters dieser Frage ist mir jedoch bewusst, dass diese Funktionalität zu diesem Zeitpunkt noch nicht verfügbar war.

Verwenden Sie die Optionen des Bson-Konstruktors für reguläre Ausdrücke, um die Groß-/Kleinschreibung zu berücksichtigen. Ich habe mir gerade den Quellcode angesehen und festgestellt, dass "ich" alles ist, was Sie brauchen. Zum Beispiel.

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

Query.Matches("MyField", bsonRegex);

Sie sollten für die Suche nicht zweimal Aufzeichnungen führen müssen.

35
Matt Canty

versuchen Sie, etwas wie folgt zu verwenden:

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

Sie müssen das Feld wahrscheinlich zweimal speichern, einmal mit dem tatsächlichen Wert und erneut in Kleinbuchstaben. Sie können dann die untergeordnete Version nach Groß- und Kleinschreibung durchsuchen (vergessen Sie nicht, auch die Abfragezeichenfolge in Kleinschreibung zu schreiben).

Dieser Ansatz funktioniert (oder ist notwendig) für viele Datenbanksysteme und sollte besser sein als Techniken, die auf regulären Ausdrücken basieren (zumindest für Präfix oder exakte Übereinstimmung).

12
Thilo

Wie i3arnon antwortete, können Sie mit Queryable einen Vergleich/eine Suche ohne Berücksichtigung von Groß- und Kleinschreibung durchführen. Was ich herausfand, war, dass ich die string.Equals () -Methode nicht verwenden konnte, weil es nicht unterstützt wird. Wenn Sie einen Vergleich durchführen müssen, ist Contains () leider nicht geeignet, wodurch ich lange Zeit um eine Lösung kämpfen musste. 

Für alle, die einen Zeichenkettenvergleich durchführen möchten, verwenden Sie einfach == statt .Equals ().

Code:

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

Falls sich jemand fragt, ob fluent-mongo add-on verwendet wird, können Sie Linq wie folgt verwenden:

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

Welche führt zu einer korrekten JS-Abfrage. Leider wird String.Equals () noch nicht unterstützt.

1
Kostassoid

Sie können auch die eingebauten Filter von MongoDB verwenden. Es kann die Verwendung einiger Methoden des Mongo erleichtern.

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

Für MongoDB 3.4 und höher empfiehlt es sich, Indizes zu verwenden. Siehe https://jira.mongodb.org/browse/DOCS-11105?focusedCommentId=1859745&page=com.atlassian.jira.plugin.system. issuetabpanels: comment-tabpanel # comment-1859745

Ich suche erfolgreich mit Groß-/Kleinschreibung nach: 1. Erstellen eines Index mit Kollatierung für ein Gebietsschema (z. B. "en") und mit einer Stärke von 1 oder 2. Siehe https://docs.mongodb.com/manual/core/index-case-insensitive/ für weitere Details

  1. Verwenden Sie die gleiche Kollatierung, wenn Sie in der MongoDb-Sammlung suchen.

Als Beispiel:

Erstellen Sie eine Sortierung mit der Stärke 1 oder 2 für Groß- und Kleinschreibung

private readonly Collation _caseInsensitiveCollation = new Collation("en", strength: CollationStrength.Primary);

Erstellen Sie einen Index. In meinem Fall indexiere ich mehrere Felder:

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);
}

Achten Sie beim Abfragen darauf, dass Sie dieselbe Sortierung verwenden:

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;
}
0
iberodev

Dazu können Sie die MongoDB.Bson.BsonJavaScript-Klasse wie unten gezeigt verwenden

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