programing

MongoDB에서 대소문자를 구분하지 않는 정렬

lovejava 2023. 3. 10. 20:59

MongoDB에서 대소문자를 구분하지 않는 정렬

MongoDB 컬렉션을 특정 필드별로 대소문자를 구분하지 않고 정렬하려면 어떻게 해야 합니까?디폴트로는 a-z보다 먼저 A-Z가 나옵니다.

업데이트: 현재 mongodb에는 대소문자를 구분하지 않는 인덱스가 있습니다.

Users.find({})
  .collation({locale: "en" })
  .sort({name: 1})
  .exec()
  .then(...)

셸:

db.getCollection('users')
  .find({})
  .collation({'locale':'en'})
  .sort({'firstName':1})

업데이트: 이 답변은 최신이 아닙니다. 3.4에는 대소문자를 구분하지 않는 인덱스가 있습니다.상세한 것에 대하여는, JIRA 를 참조해 주세요.https://jira.mongodb.org/browse/SERVER-90


안타깝게도 MongoDB에는 아직 대소문자를 구분하지 않는 인덱스가 없습니다.https://jira.mongodb.org/browse/SERVER-90 및 작업은 뒤로 미뤄졌습니다.

즉, 현재 대소문자를 구분하지 않고 정렬할 수 있는 유일한 방법은 특정 "소문자 구분" 필드를 실제로 만들고 해당 정렬 필드의 값(물론 소문자 구분)을 복사하여 대신 정렬하는 것입니다.

정렬은 MongoDB와 동일하게 동작하지만 Aggregate를 사용하여 즉시 수행할 수 있습니다.

다음 데이터를 취합합니다.

{ "field" : "BBB" }
{ "field" : "aaa" }
{ "field" : "AAA" }

그래서 다음과 같은 문구를 사용합니다.

db.collection.aggregate([
    { "$project": {
       "field": 1,
       "insensitive": { "$toLower": "$field" }
    }},
    { "$sort": { "insensitive": 1 } }
])

다음과 같은 결과를 얻을 수 있습니다.

{
    "field" : "aaa",
    "insensitive" : "aaa"
},
{
    "field" : "AAA",
    "insensitive" : "aaa"
},
{
    "field" : "BBB",
    "insensitive" : "bbb"
}

실제 삽입 순서는 변환 시 동일한 키가 되는 값에 대해 유지됩니다.

이것은 MongoDB JIRA에서 오랫동안 문제가 되어 왔지만, 지금은 해결되었습니다.상세한 것에 대하여는, 이 릴리스 노트를 참조해 주세요.를 사용해 주세요.collation.

User.find()
    .collation({locale: "en" }) //or whatever collation you want
    .sort({name:1})
    .exec(function(err, users) {
        // use your case insensitive sorted results
    });

코드 추가.collation({'locale':'en'})내 문제를 해결하는 데 도움을 줬어

현재(mongodb 4)에서는 다음 작업을 수행할 수 있습니다.

mongo 쉘:

db.getCollection('users')
  .find({})
  .collation({'locale':'en'})
  .sort({'firstName':1});

mongoose:

Users.find({})
  .collation({locale: "en" })
  .sort({name: 1})
  .exec()
  .then(...)

다음은 mongodb가 지원하는 언어로케일입니다.

Mongoose의 경우:-

Customer.find()
  .collation({locale: "en" })
  .sort({comapany: 1})

자바어로 되어 있습니다.no-args와 첫 번째 키-발 변형을 혼합했습니다.BasicDBObject단지 다양성 때문에

        DBCollection coll = db.getCollection("foo");

        List<DBObject> pipe = new ArrayList<DBObject>();

        DBObject prjflds = new BasicDBObject();
        prjflds.put("field", 1);
        prjflds.put("insensitive", new BasicDBObject("$toLower", "$field"));

        DBObject project = new BasicDBObject();
        project.put("$project", prjflds);
        pipe.add(project);

        DBObject sort = new BasicDBObject();
        sort.put("$sort", new BasicDBObject("insensitive", 1));
        pipe.add(sort);

        AggregationOutput agg = coll.aggregate(pipe);

        for (DBObject result : agg.results()) {
            System.out.println(result);
        }

문서의 모든 데이터를 정렬하고 반환하려면 다음을 추가할 수 있습니다.document: "$$ROOT"

db.collection.aggregate([
  { 
    $project: {
      field: 1,
      insensitive: { $toLower: "$field" },
      document: "$$ROOT"
    }
  },
  { $sort: { insensitive: 1 } }
]).toArray()

위의 모든 것을 시도해 보고 응답하여 결과를 통합.

답변-1:

db.collection.aggregate([
    { "$project": {
       "field": 1,
       "insensitive": { "$toLower": "$field" }
    }},
    { "$sort": { "insensitive": 1 } } ])

Aggregate 쿼리는 필드를 더 낮게 변환하므로 대용량 데이터의 경우 성능이 낮습니다.

답변-2:

db.collection.find({}).collation({locale: "en"}).sort({"name":1})

기본적으로는 mongo는 uft-8 인코딩(Z는 priority가 a보다 높음) 규칙을 따르기 때문에 언어 고유의 규칙으로 덮어씁니다.위의 쿼리와 빠른 비교 규칙을 커스터마이즈하려면 공식 문서를 참조하십시오.

https://docs.mongodb.com/manual/reference/collation/

이 문제는 JavaScript 배열의 .sort 함수를 사용하여 해결합니다.

여기 코드가 있습니다.


함수 foo() {결과 = collections.findfind에 맡기십시오._id: _id}, {필드: {'접속': 1,}}).fetch();
results.param((a, b)=>{var nameA = a.username.toUpperCase();var nameB = b.username.toUpperCase();
(이름 A B)의 경우}반환 1;}0을 반환한다.});
결과를 반환하다}

언급URL : https://stackoverflow.com/questions/22931177/case-insensitive-sorting-in-mongodb