source

MongoDB 및 C#: 대소문자 구분 안 함 검색

ittop 2023. 5. 17. 23:25
반응형

MongoDB 및 C#: 대소문자 구분 안 함 검색

저는 MongoDB와 MongoDB용 C# 드라이버사용하고 있습니다.

저는 최근에 MongoDB의 모든 쿼리가 대소문자를 구분한다는 것을 발견했습니다.대소문자를 구분하지 않는 검색을 수행하려면 어떻게 해야 합니까?

한 가지 방법을 찾았습니다.

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

이를 위한 가장 간단하고 안전한 방법은Linq:

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

자습서에 설명된 대로 ToLower,ToLowerInvariant,ToUpper그리고.ToUpperInvariant모두 대소문자를 구분하지 않는 방식으로 일치를 수행합니다.그런 다음 다음과 같은 모든 지원되는 문자열 방법을 사용할 수 있습니다.Contains또는StartsWith.

이 예는 다음을 생성합니다.

{
    "FirstName" : /hamster/is
}

i옵션을 선택하면 대소문자가 구분되지 않습니다.

저는 다른 어떤 제안보다 훨씬 더 간단하게 이것을 구현했습니다.그러나 이 질문의 나이 때문에 이 기능은 당시에는 사용할 수 없었을 수도 있다는 것을 알고 있습니다.

Bson 정규식 생성자의 옵션을 사용하여 대소문자를 구분하지 않고 전달합니다.방금 소스 코드를 봤는데 'i'만 있으면 됩니다.예를들면.

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

Query.Matches("MyField", bsonRegex);

검색을 위해 기록을 두 번 보관할 필요가 없습니다.

다음과 같은 것을 사용해 보십시오.

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

필드를 두 번 저장해야 합니다. 한 번은 실제 값으로 저장하고 다시 모두 소문자로 저장해야 합니다.그런 다음 소문자 버전을 쿼리하여 대소문자를 구분하지 않는 검색을 수행할 수 있습니다(쿼리 문자열도 소문자로 표시).

이 접근 방식은 많은 데이터베이스 시스템에서 작동(또는 필요)하며, 적어도 접두사 또는 정확한 일치에 대해서는 정규식 기반 기술보다 더 나은 성능을 발휘해야 합니다.

i3arnon이 답변했듯이 Queryable을 사용하여 대소문자를 구분하지 않는 비교/검색을 수행할 수 있습니다.제가 알아낸 것은 끈을 사용할 수 없다는 것입니다.지원되지 않으므로 Equals() 메서드입니다.비교가 필요한 경우 Contains()는 안타깝게도 적합하지 않아 한동안 해결책을 찾지 못했습니다.

문자열 비교를 원하는 사용자는 대신 ==를 사용하면 됩니다.등호().

코드:

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

MongoDB 3.4+의 경우 인덱스를 사용하는 것이 좋습니다.https://jira.mongodb.org/browse/DOCS-11105?focusedCommentId=1859745&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-1859745 을 참조하십시오.

대소문자를 구분하지 않고 성공적으로 검색하고 있습니다. 1. 로케일(예: "en")에 대해 콜리메이션을 사용하여 인덱스를 만들고 1 또는 2.자세한 내용은 https://docs.mongodb.com/manual/core/index-case-insensitive/ 를 참조하십시오.

  1. MongoDb 컬렉션에서 검색을 수행할 때 동일한 정렬 사용.

예를 들어,

대/소문자를 구분하지 않는 강도 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;
}

MongoDB의 내장 필터를 사용할 수도 있습니다.그것은 몽고의 몇 가지 방법을 사용하는 것을 더 쉽게 만들 수 있습니다.

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

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

Fluent-mongo 애드온을 사용하여 궁금한 사람이 있을 경우, Linkq를 사용하여 다음과 같이 쿼리할 수 있습니다.

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

그러면 올바른 JS 쿼리가 생성됩니다.불행하게도, String.등호()는 아직 지원되지 않습니다.

방법은 MongoDB를 사용하는 것입니다.Bson.BsonJavaScript 클래스는 아래와 같습니다.

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

이것은 정확한 텍스트 검색이며 대소문자를 구분하지 않습니다( 링크 참조).

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

언급URL : https://stackoverflow.com/questions/4458950/mongodb-and-c-case-insensitive-search

반응형