var thename = 'Andrew';
db.collection.find({'name':thename});
대소 문자를 구분하지 않는 쿼리는 어떻게합니까? "andrew"라고해도 결과를 찾고 싶습니다.
var thename = 'Andrew';
db.collection.find({'name':thename});
대소 문자를 구분하지 않는 쿼리는 어떻게합니까? "andrew"라고해도 결과를 찾고 싶습니다.
답변:
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")
과 같이 조정하십시오 .
".*"
.
이 경우 대소 문자를 구분하지 않는 정규식 을 사용해야합니다 . 예 :
db.collection.find( { "name" : { $regex : /Andrew/i } } );
thename
변수 에서 정규식 패턴을 사용하려면 새 RegExp 개체를 생성 합니다.
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
업데이트 : 정확히 일치하려면 regex를 사용해야합니다 "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});
이렇게하면 '뉴욕', '뉴욕', '뉴욕'등의 도시가 반환됩니다.
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 }})
두 줄은 모두 대소 문자를 구분하지 않습니다. DB의 이메일이 될 수 NaMe@CompanY.Com
있으며 두 줄 모두 DB에서 개체를 찾습니다.
마찬가지로, 우리 는 DB에서 /^NaMe@CompanY.Com$/i
이메일을 사용할 수 있습니다 name@company.com
.
대소 문자를 구분하지 않는 문자열을 찾으려면 이것을 사용하십시오.
var thename = "Andrew";
db.collection.find({"name":/^thename$/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
... 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$
MongoDB에서 Mongoose ORM을 사용하는 Javascript, NodeJS의 전체 코드 예제
// 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);
});
});
대소 문자를 구분하지 않는 리터럴 문자열을 찾으려면 :
db.collection.find({
name: {
$regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
}
});
db.collection.find({
name_lower: name.toLowerCase()
});
정규식은 리터럴 문자열 일치보다 느립니다. 그러나 추가 소문자 필드는 코드 복잡성을 증가시킵니다. 확실하지 않은 경우 정규식을 사용하십시오. 필드를 대체 할 수있는 경우에만 명시 적으로 소문자 필드를 사용하는 것이 좋습니다. 즉, 처음에는 대소 문자를 신경 쓰지 않습니다.
정규식 전에 이름을 이스케이프해야합니다. 사용자 입력 와일드 카드를 원하는 경우 .replace(/%/g, '.*')
"a"로 시작하는 모든 이름을 찾기 위해 "a %"와 일치 할 수 있도록 이스케이프 후 추가 하는 것이 좋습니다.
대소 문자를 구분하지 않는 색인을 사용할 수 있습니다 .
다음 예제에서는 기본 데이터 정렬이없는 컬렉션을 만든 다음 대소 문자를 구분하지 않는 데이터 정렬을 사용하여 이름 필드에 인덱스를 추가합니다. 유니 코드 용 국제 구성 요소
/*
* 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
쉬운 방법은 아래와 같이 $ toLower를 사용하는 것입니다.
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])