[MONGODB] 절 보증 순서에서와 MongoDB를의 $
MONGODB절 보증 순서에서와 MongoDB를의 $
절에 MongoDB를의 $를 사용하는 경우, 반환 된 문서 배열 인수의 순서에 항상 대응의 순서를합니까?
해결법
-
==============================
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.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.당신이 집계 사용하지 않을 경우, 다른 솔루션은 사용 찾을 수 있습니다 다음 종류의 종류의 배열 번호를 사용하여 문서 결과를 클라이언트 측 :
당신이 집계 사용하지 않을 경우, 다른 솔루션은 사용 찾을 수 있습니다 다음 종류의 종류의 배열 번호를 사용하여 문서 결과를 클라이언트 측 :
값에 $가 번호와 같은 기본 유형 인 경우에는 같은 방법을 사용할 수 있습니다 :
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.지도의 조합 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.몽고 돌아 오면 배열을 결과를 주문하는 쉬운 방법은 키로 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.항상? 못. 정의되지 않은 (문서가 저장되는 아마 실제 순서) : 순서는 항상 동일합니다. 당신이하지 않으면 그것을 정렬합니다.
항상? 못. 정의되지 않은 (문서가 저장되는 아마 실제 순서) : 순서는 항상 동일합니다. 당신이하지 않으면 그것을 정렬합니다.
-
==============================
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.나는이 오래된 스레드 알지만, 당신은 단지 배열의 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.당신은 $ 또는 절을 순서를 보장 할 수 있습니다.
당신은 $ 또는 절을 순서를 보장 할 수 있습니다.
그래서 $ 또는 사용 : [_ids.map을 (_id => ({_id}))] 대신.
-
==============================
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++ } } }
from https://stackoverflow.com/questions/22797768/does-mongodbs-in-clause-guarantee-order by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] MongoDB의에서 임의의 기록 (0) | 2019.11.29 |
---|---|
[MONGODB] 컬렉션에서 모든 키의 이름을 가져옵니다 (0) | 2019.11.29 |
[MONGODB] 두 번 중첩 된 배열에서 찾기 MongoDB를 (0) | 2019.11.29 |
[MONGODB] MongoDB의 15 분의 시간 간격에 의한 그룹 결과 (0) | 2019.11.29 |
[MONGODB] 몽구스의 채우기 후 쿼리 (0) | 2019.11.29 |