2013-07-31 7 views
0

다음 SQL 명령에서와 같이 mongoDB를 사용하여 태국어 필드를 정렬하는 방법은 무엇입니까?mongoDB를 사용하여 태국어 필드를 정렬하는 방법

SELECT * FROM employee ORDER BY CONVERT(name USING tis620) 
+3

현재 MongoDb는 언어별로 정렬 할 수있는 데이터 정렬 기준으로 정렬 할 수는 없지만 목록에서 상위에 있습니다 : https://jira.mongodb.org/browse/SERVER-1920 – Sammaye

+0

답장을 보내 주셔서 감사합니다. @ 사 마예 – wannik

답변

1

지금은 MongoDB가 "유니 코드 코드 포인트"이외의 것으로 정렬 할 수 없습니다. 문제 추적기에 문제가 있습니다 : https://jira.mongodb.org/browse/SERVER-1920 로캘 기반 및 대소 문자를 구분하지 않는 정렬을 MongoDB에 포함시키는 것을 추적합니다.

0

사실, 방법이 있습니다! (비록 해킹이지만).

나는 이것이 오래된 스레드라는 것을 알고 있지만 어쨌든 대답하는 것이 유용 할 것이라고 생각한다.

당신은 분명히 당신의 앱에서 정렬을하고 싶지 않습니다. 왜냐하면 당신은 콜렉션의 모든 문서를 정렬하고 정렬하여 원하는 창을 돌려 주어야하기 때문입니다. 컬렉션이 거대한 경우 매우 비효율적입니다. 데이터베이스는 정렬을 수행하고 창을 사용자에게 반환해야합니다.

그러나 MongoDB는 로케일 구분 정렬을 지원하지 않습니다. 어떻게 문제를 해결합니까? 마술은 "정렬 키"의 개념입니다.

기본적으로 영어/라틴 알파벳이 "a"에서 "z"까지 있다고 가정 해 보겠습니다. 당신은 "a"에서 "01"그리고 "b"에서 "02"등, "z"에서 "26"까지의 정렬 키 매핑을 생성합니다. 즉, 모든 문자를 해당 언어의 정렬 순서로 숫자에 매핑 한 다음 해당 숫자를 문자열로 인코딩합니다. 그런 다음 정렬 할 문자열을이 유형의 정렬 키에 매핑하십시오. 예를 들어, "abc"는 "010203"이됩니다. 그런 다음 속성에 대한 정렬 키를 사용하여 문서에 속성을 추가하고, 로케일의 이름 속성의 이름을 추가합니다

{ 
    name: "abc", 
    name_en: "010203" 
} 

은 이제 언어로 정렬 할 수 있습니다 단지 색인에 의해 "엉" name_en "속성을 사용하고"name "속성 대신 선택자와 범위에 대해 오래된 영어 기반 MongoDB 정렬을 사용합니다.

이제 'abc'대신 알파벳의 순서가 'acb'인 또 다른 미친 언어 'xx'가 있다고 가정 해 보겠습니다. (예, 언어가 패션 라틴 알파벳의 순서가 엉망이 있습니다!) 정렬 키는 다음과 같이 될 것이다 : 이제

{ 
    name: "abc", 
    name_en: "010203", 
    name_xx: "010302" 
} 

, 당신이 할 일은 name_en 및 name_xx과에 인덱스를 만드는 것입니다 해당 로케일에서 올바르게 정렬하려면 일반 MongoDB 정렬을 사용하십시오. 기본적으로 추가 속성은 다른 로케일에서 정렬하기위한 프록시입니다.

그래서 이러한 매핑을 어디서 구합니까? 결국 세계화 전문가가 아니시겠습니까?

Java, C 또는 C++를 사용하는 경우이 맵핑을 수행 할 수있는 기성 클래스가있을 수 있습니다. Java에서는 표준 Collator 클래스를 사용하거나 icu4j Collator 클래스를 사용하십시오. C/C++를 사용하는 경우 ICU Collator 함수/클래스의 C/C++ 버전을 사용하십시오. 다른 언어의 경우, 이미 그것을하는 라이브러리를 찾을 수 없다면 일종의 비합리적입니다.

자바와 ICU가 모두 태국어 로켈을 지원하며 태국어로 적절한 정렬을 할 수 있음을 알고 있습니다. 모든 문자열이 UTF-8로 올바르게 인코딩되었는지 확인하십시오.여기

당신이 그들을 찾을 수 있도록 몇 가지 링크입니다 :

표준 자바 라이브러리 조합기 : http://docs.oracle.com/javase/7/docs/api/java/text/Collator.html#getCollationKey(java.lang.String)

는 C++ Collator 클래스 : http://icu-project.org/apiref/icu4c/classicu_1_1Collator.html#ae0bc68d37c4a88d1cb731adaa5a85e95

또한 당신을 수있는 다른 종류의 키를 만들 수 있습니다 로케일별로 대소 문자를 구분하지 않고 (예, 대소 문자 매핑은 로케일에 민감합니다!) 및 액센트 비 감도로 유니 코드 변형을 구분하지 않습니다. 유일한 문제는 이제 각각의 정렬 가능한 속성을 병렬화하는 많은 속성을 갖고 있으며 기본 "이름"속성을 업데이트 할 때 모든 속성을 동기화 상태로 유지해야한다는 것입니다. 그것은 당신의 아픔입니다.하지만 여전히 앱이나 비즈니스 로직 레이어에서 정렬하는 것보다 낫습니다.

범위가있는 커서도주의하십시오. 예를 들어 영어에서는 문자의 악센트 만 무시합니다. 따라서 "Ö"는 "O"와 같은 방식으로 정렬되며 범위 "M"에서 "Z"로 나타납니다. 그러나 스웨덴어에서는 악센트 부호가있는 문자가 "Z"뒤에 정렬됩니다. 따라서 범위 "M"- "Z"를 지정하면 스웨덴어가 아닌 "Ö"로 시작하는 많은 레코드가 영어로 포함됩니다.

문서의 텍스트 속성으로 분할하는 경우 샤딩에 영향을 미칩니다. 어떤 범위가 어떤 샤드로 들어가는 지 조심하십시오. 로케일에 민감하지 않은 것들, 예를 들어 해시 같은 것들을 파헤치는 것이 낫습니다.

관련 문제