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/ 를 참조하십시오.
- 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
'source' 카테고리의 다른 글
단일 쿼리에서 mongo에서 여러 문서 제거 (0) | 2023.05.17 |
---|---|
ASP.NET의 세션 시간 초과 (0) | 2023.05.17 |
"다른 프로세스에서 사용 중" 예외가 발생한 경우에도 파일을 읽는 방법은 무엇입니까? (0) | 2023.05.17 |
날짜 시간에서 하루 빼기 (0) | 2023.05.12 |
GitLab 원격: HTTP Basic:액세스 거부 및 치명적인 인증 (0) | 2023.05.12 |