1. 유니코드 정규화(NFC vs NFD) 차이로 인한 검색 오류
MongoDB에서 텍스트 검색을 수행할 때, 유니코드 정규화 방식(Normalization Form)이 다르면 같은 문자열이라도 다르게 인식됩니다. 예를 들어, 한글이나 특수 문자가 포함된 텍스트를 검색할 때 NFC(Normalization Form C)와 NFD(Normalization Form D) 방식의 차이로 인해 조회되지 않는 문제가 발생할 수 있습니다. 이 문제는 MacOS 또는 특정 환경에서 텍스트가 NFD 형태로 저장되었지만, 검색 시 NFC 형식으로 입력되었을 때 자주 발생합니다.
2. 유니코드 정규화란?
유니코드에서는 같은 문자를 여러 방식으로 표현할 수 있습니다. 예를 들어, 한글 "가"는 다음 두 가지 방식으로 표현될 수 있습니다.
- NFC (Normalization Form C): 조합된 형태 → "가"
- NFD (Normalization Form D): 분해된 형태 → "ᄀ" + "ᅡ"
console.log('가' === '\u1100\u1161'); // false (NFC vs NFD)
console.log('가'.normalize('NFC') === '\u1100\u1161'.normalize('NFC')); // true이처럼 MongoDB에 저장된 문자열이 NFC인지 NFD인지에 따라 동일한 텍스트라도 검색 결과가 달라질 수 있습니다.
3. NFC와 NFD 차이로 인한 검색 오류
MongoDB에 한글 데이터를 저장하고, 동일한 문자열을 조회할 때 조회되지 않는 사례를 살펴보겠습니다.
3-1. 데이터 삽입 (NFC 형태)
db.products.insertOne({ name: "컴퓨터" });3-1. 3-2. 검색 (NFD 형태로 입력)
db.products.find({ name: "컴퓨터" });위와 같이 컴퓨터라는 문자열이 NFC로 저장되었지만, 검색 시 NFD 형태로 입력되면 조회되지 않습니다. 이는 MongoDB가 기본적으로 유니코드 정규화를 적용하지 않기 때문입니다.
4. 해결 방법
4-1. 저장 시 모든 데이터를 NFC로 정규화
데이터를 삽입하기 전에 NFC로 변환하여 저장하면 문제를 예방할 수 있습니다.
db.products.insertOne({ name: "컴퓨터".normalize("NFC") });4-2. 검색 시 정규화 적용
검색 시에도 입력 데이터를 NFC로 변환하여 조회하면 문제를 해결할 수 있습니다.
db.products.find({ name: "컴퓨터".normalize("NFC") });4-3. MongoDB에서 collation을 활용한 정규화
MongoDB의 collation 기능을 활용하면 유니코드 문자열 비교 방식을 개선할 수 있습니다. 이 방법을 사용하면 한글이나 특수 문자가 포함된 데이터의 정렬 및 검색이 더 일관성 있게 수행됩니다.
db.products.find(
{ name: "컴퓨터" },
{ collation: { locale: "ko", strength: 1 } }
);- locale: "ko" → 한국어 정렬 방식 적용
- strength: 1 → 문자 비교 시 정규화 차이를 무시하도록 설정
이 방법은 문자열 검색뿐만 아니라, 정렬 시에도 유니코드 정규화 차이를 무시하도록 설정할 수 있어 유용합니다.
5. 결론
- MongoDB는 기본적으로 유니코드 정규화를 적용하지 않기 때문에, NFC와 NFD 차이로 인해 동일한 텍스트라도 검색이 실패할 수 있습니다. 따라서 데이터를 삽입하기 전에 NFC로 변환하여 저장하고, 검색 시에도 .normalize("NFC")를 적용하면 문제 해결 가능합니다. 또한, MongoDB collation 기능을 활용하면 검색 및 정렬 시 유니코드 정규화 차이를 줄일 수 있습니다.