복붙노트

[MONGODB] 절 보증 순서에서와 MongoDB를의 $

MONGODB

절 보증 순서에서와 MongoDB를의 $

절에 MongoDB를의 $를 사용하는 경우, 반환 된 문서 배열 인수의 순서에 항상 대응의 순서를합니까?

해결법

  1. ==============================

    1.언급 한 바와 같이, 절에 $의 배열 인수의 순서는 문서를 검색하는 방법의 순서를 반영하지 않습니다. 물론 도시 된 바와 같이 그 자연 순서 또는 선택된 번호순으로있을 것이다.

    언급 한 바와 같이, 절에 $의 배열 인수의 순서는 문서를 검색하는 방법의 순서를 반영하지 않습니다. 물론 도시 된 바와 같이 그 자연 순서 또는 선택된 번호순으로있을 것이다.

    이 순서를 유지해야하는 경우에, 당신은 기본적으로 두 가지 옵션이 있습니다.

    그럼 당신은 [4, 2, 8]로의 $에 전달 될 예정이다 배열과 문서에 _id의 값에 일치되었다고 가정 해 봅시다.

    var list = [ 4, 2, 8 ];
    
    db.collection.aggregate([
    
        // Match the selected documents by "_id"
        { "$match": {
            "_id": { "$in": [ 4, 2, 8 ] },
        },
    
        // Project a "weight" to each document
        { "$project": {
            "weight": { "$cond": [
                { "$eq": [ "$_id", 4  ] },
                1,
                { "$cond": [
                    { "$eq": [ "$_id", 2 ] },
                    2,
                    3
                ]}
            ]}
        }},
    
        // Sort the results
        { "$sort": { "weight": 1 } }
    
    ])
    

    그래서 확장 된 형태 일 것이다. 무엇 기본적으로 여기에서 발생하는 값의 배열 $에 전달되는 것처럼 당신은 또한 값을 테스트하고 적절한 가중치를 부여하는 "중첩"$ COND 문을 구성에 있다는 것입니다. 그 "무게"값이 배열의 요소의 순서를 반영, 당신은 다음 필요한 순서대로 결과를 얻기 위해 정렬 단계로 그 값을 전달할 수 있습니다.

    물론 실제로 많은 같은 "빌드"코드의 파이프 라인 문의 :

    var list = [ 4, 2, 8 ];
    
    var stack = [];
    
    for (var i = list.length - 1; i > 0; i--) {
    
        var rec = {
            "$cond": [
                { "$eq": [ "$_id", list[i-1] ] },
                i
            ]
        };
    
        if ( stack.length == 0 ) {
            rec["$cond"].push( i+1 );
        } else {
            var lval = stack.pop();
            rec["$cond"].push( lval );
        }
    
        stack.push( rec );
    
    }
    
    var pipeline = [
        { "$match": { "_id": { "$in": list } }},
        { "$project": { "weight": stack[0] }},
        { "$sort": { "weight": 1 } }
    ];
    
    db.collection.aggregate( pipeline );
    

    모두가 당신의 감성에 대한 무거운에 보인다 물론 당신은 간단하게 보이지만 가능성이 다소 느리게 실행됩니다 맵리 듀스를 사용하여 같은 일을 할 수 있다면.

    var list = [ 4, 2, 8 ];
    
    db.collection.mapReduce(
        function () {
            var order = inputs.indexOf(this._id);
            emit( order, { doc: this } );
        },
        function() {},
        { 
            "out": { "inline": 1 },
            "query": { "_id": { "$in": list } },
            "scope": { "inputs": list } ,
            "finalize": function (key, value) {
                return value.doc;
            }
        }
    )
    

    그리고 기본적들이 입력 배열에서 발생 방법의 "인덱스 순서"에있는 방출 "키"값에 의존한다.

    그 그래서 본질적으로 이미 결정된 순서로 그 목록이 조건에 $에 입력 목록의 순서를 유지하는 당신의 방법이 있습니다.

  2. ==============================

    2.MongoDB의 버전에만 적용 집계 쿼리를 사용하는 또 다른 방법> = 3.4 -

    MongoDB의 버전에만 적용 집계 쿼리를 사용하는 또 다른 방법> = 3.4 -

    신용이 좋은 블로그 게시물로 이동합니다.

    예 문서의 순서로 반입 할 수 -

    var order = [ "David", "Charlie", "Tess" ];
    

    쿼리 -

    var query = [
                 {$match: {name: {$in: order}}},
                 {$addFields: {"__order": {$indexOfArray: [order, "$name" ]}}},
                 {$sort: {"__order": 1}}
                ];
    
    var result = db.users.aggregate(query);
    

    사용이 집계 연산자를 설명하는 게시물의 또 다른 인용 -

    그것을 발견하고이 순서 필드는 우리가 제공하는 우리의 배열의 원래 순서를 나타낼 때 기본적으로 addFields 운영자는 모든 문서에 새로운 질서 필드를 추가합니다. 그런 다음 우리는 단순히이 필드를 기준으로 문서를 정렬합니다.

  3. ==============================

    3.당신이 집계 사용하지 않을 경우, 다른 솔루션은 사용 찾을 수 있습니다 다음 종류의 종류의 배열 번호를 사용하여 문서 결과를 클라이언트 측 :

    당신이 집계 사용하지 않을 경우, 다른 솔루션은 사용 찾을 수 있습니다 다음 종류의 종류의 배열 번호를 사용하여 문서 결과를 클라이언트 측 :

    값에 $가 번호와 같은 기본 유형 인 경우에는 같은 방법을 사용할 수 있습니다 :

    var ids = [4, 2, 8, 1, 9, 3, 5, 6];
    MyModel.find({ _id: { $in: ids } }).exec(function(err, docs) {
        docs.sort(function(a, b) {
            // Sort docs by the order of their _id values in ids.
            return ids.indexOf(a._id) - ids.indexOf(b._id);
        });
    });
    

    값에 $으로하며 Object 같은 비 기본 유형이 있다면 같이 IndexOf으로 필요한 다른 방법은이 경우에 참고로 비교한다.

    당신은 Node.js를이 4.x의 +, 당신은 배열 # findIndex을 사용할 수 있습니다 사용하는 경우 및 OBJECTID #은에 정렬 기능을 변경하여이 문제를 처리하기 위해 같다 :

    docs.sort((a, b) => ids.findIndex(id => a._id.equals(id)) - 
                        ids.findIndex(id => b._id.equals(id)));
    

    또는 밑줄 / lodash의 findIndex 어떤 Node.js를 버전과 :

    docs.sort(function (a, b) {
        return _.findIndex(ids, function (id) { return a._id.equals(id); }) -
               _.findIndex(ids, function (id) { return b._id.equals(id); });
    });
    
  4. ==============================

    4.지도의 조합 ECMA 스크립트 2015에서 Array.prototype.find 기능 (클라이언트가 자바 스크립트에있는 경우) JonnyHK의 솔루션과 마찬가지로, 당신은 당신의 클라이언트에서 발견에서 반환 된 문서의 순서를 변경할 수 있습니다 :

    지도의 조합 ECMA 스크립트 2015에서 Array.prototype.find 기능 (클라이언트가 자바 스크립트에있는 경우) JonnyHK의 솔루션과 마찬가지로, 당신은 당신의 클라이언트에서 발견에서 반환 된 문서의 순서를 변경할 수 있습니다 :

    Collection.find({ _id: { $in: idArray } }).toArray(function(err, res) {
    
        var orderedResults = idArray.map(function(id) {
            return res.find(function(document) {
                return document._id.equals(id);
            });
        });
    
    });
    

    노트의 몇 :

  5. ==============================

    5.몽고 돌아 오면 배열을 결과를 주문하는 쉬운 방법은 키로 ID로 객체를 만든 다음, 지정된 _id의가 올바르게 정렬 된 배열을 반환 이상 매핑하는 것이다.

    몽고 돌아 오면 배열을 결과를 주문하는 쉬운 방법은 키로 ID로 객체를 만든 다음, 지정된 _id의가 올바르게 정렬 된 배열을 반환 이상 매핑하는 것이다.

    async function batchUsers(Users, keys) {
      const unorderedUsers = await Users.find({_id: {$in: keys}}).toArray()
      let obj = {}
      unorderedUsers.forEach(x => obj[x._id]=x)
      const ordered = keys.map(key => obj[key])
      return ordered
    }
    
  6. ==============================

    6.항상? 못. 정의되지 않은 (문서가 저장되는 아마 실제 순서) : 순서는 항상 동일합니다. 당신이하지 않으면 그것을 정렬합니다.

    항상? 못. 정의되지 않은 (문서가 저장되는 아마 실제 순서) : 순서는 항상 동일합니다. 당신이하지 않으면 그것을 정렬합니다.

  7. ==============================

    7.나는이 질문에 몽구스 JS 프레임 워크 관련이 알고 있지만, 내가 파이썬 (PyMongo) 솔루션은 여기 괜찮 게시 희망 있도록 중복 된 사람은 일반입니다.

    나는이 질문에 몽구스 JS 프레임 워크 관련이 알고 있지만, 내가 파이썬 (PyMongo) 솔루션은 여기 괜찮 게시 희망 있도록 중복 된 사람은 일반입니다.

    things = list(db.things.find({'_id': {'$in': id_array}}))
    things.sort(key=lambda thing: id_array.index(thing['_id']))
    # things are now sorted according to id_array order
    
  8. ==============================

    8.나는이 오래된 스레드 알지만, 당신은 단지 배열의 ID 값을 반환하는 경우, 당신은이 구문을 선택하는있을 수 있습니다. 내가 얻을 수가 없습니다으로 같이 IndexOf 값은 몽고 ObjectId가 형식과 일치합니다.

    나는이 오래된 스레드 알지만, 당신은 단지 배열의 ID 값을 반환하는 경우, 당신은이 구문을 선택하는있을 수 있습니다. 내가 얻을 수가 없습니다으로 같이 IndexOf 값은 몽고 ObjectId가 형식과 일치합니다.

      obj.map = function() {
        for(var i = 0; i < inputs.length; i++){
          if(this._id.equals(inputs[i])) {
            var order = i;
          }
        }
        emit(order, {doc: this});
      };
    

    단지 값 - 어떻게 래퍼 'ObjectId가 ()를'포함하지 않고 몽고 ObjectId가로 .toString를 변환하는?

  9. ==============================

    9.당신은 $ 또는 절을 순서를 보장 할 수 있습니다.

    당신은 $ 또는 절을 순서를 보장 할 수 있습니다.

    그래서 $ 또는 사용 : [_ids.map을 (_id => ({_id}))] 대신.

  10. ==============================

    10.결과가 몽고에서 검색 한 후이 코드 솔루션입니다. 저장 지수에 대한지도를 사용하여 다음 값을 교환.

    결과가 몽고에서 검색 한 후이 코드 솔루션입니다. 저장 지수에 대한지도를 사용하여 다음 값을 교환.

    catDetails := make([]CategoryDetail, 0)
    err = sess.DB(mdb).C("category").
        Find(bson.M{
        "_id":       bson.M{"$in": path},
        "is_active": 1,
        "name":      bson.M{"$ne": ""},
        "url.path":  bson.M{"$exists": true, "$ne": ""},
    }).
        Select(
        bson.M{
            "is_active": 1,
            "name":      1,
            "url.path":  1,
        }).All(&catDetails)
    
    if err != nil{
        return 
    }
    categoryOrderMap := make(map[int]int)
    
    for index, v := range catDetails {
        categoryOrderMap[v.Id] = index
    }
    
    counter := 0
    for i := 0; counter < len(categoryOrderMap); i++ {
        if catId := int(path[i].(float64)); catId > 0 {
            fmt.Println("cat", catId)
            if swapIndex, exists := categoryOrderMap[catId]; exists {
                if counter != swapIndex {
                    catDetails[swapIndex], catDetails[counter] = catDetails[counter], catDetails[swapIndex]
                    categoryOrderMap[catId] = counter
                    categoryOrderMap[catDetails[swapIndex].Id] = swapIndex
                }
                counter++
            }
        }
    }
    
  11. from https://stackoverflow.com/questions/22797768/does-mongodbs-in-clause-guarantee-order by cc-by-sa and MIT license