2011-02-23 1 views
20

다음 형식의 콜렉션을 가진 mongoDB을 사용하고 있습니다.mongodb 다른 레코드를 얻으십시오

{"id" : 1 , name : x ttm : 23 , val : 5 } 
{"id" : 1 , name : x ttm : 34 , val : 1 } 
{"id" : 1 , name : x ttm : 24 , val : 2 } 
{"id" : 2 , name : x ttm : 56 , val : 3 } 
{"id" : 2 , name : x ttm : 76 , val : 3 } 
{"id" : 3 , name : x ttm : 54 , val : 7 } 
이 같은 내림차순으로 기록을 얻기 위해 조회 한 그 컬렉션

:

db.foo.find({"id" : {"$in" : [1,2,3]}}).sort(ttm : -1).limit(3) 

그러나 같은 id = 1의 두 개의 레코드를 제공하고 나는 그것이 id 당 한 기록을 제공하도록 기록을합니다.

mongodb에서 가능합니까?

답변

25

mongodb에는 쿼리와 함께 사용할 수있는 distinct 명령이 있습니다. 그러나 이것은 당신이 특정 키에 대한 고유 한 값 목록을 반환한다고 믿습니다 (즉, 귀하의 경우에는 반환 된 id 값만 가져옵니다). 그래서 이것이 당신이 원하는 경우 정확히 당신에게 줄 것이라고 확신하지 않습니다. 전체 문서가 필요합니다. 대신 MapReduce가 필요할 수 있습니다. 별개의

문서는 : http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct

+0

덕분에, 그래, 나는 전체 문서를 원하는 있지만 중복 된 ID 문서 –

+0

'별개의 (: ID)'반환 전체 문서 중복 된 ID없이. – Voldy

+1

@Voldy - 문구 쉘에서 작동하는 구문을 가져올 수 없으며 구문 오류가 발생합니다. – AdaTheDev

6

문제는 일치하는 결과 사이에서 선택하는 방법에 대한 쿼리에서 어떤 논리를 제공하지 않고 하나에 이르기까지 3 개 일치하는 레코드를 증류 할 것입니다.

옵션은 기본적으로 일종의 집계 논리를 지정하거나 (예 : 각 열의 최대 값 또는 최소값 선택) 선택 고유 쿼리를 실행하고 고유하게하려는 필드 만 선택하는 것입니다.

querymongo.com (SQL에서 MongoDB로)이 별개의 쿼리를 번역하는 것은 훌륭합니다. 예를 들어

이 SQL :

SELECT DISTINCT columnA FROM collection WHERE columnA > 5 

이 MongoDB를로 반환됩니다 : 당신은 자바 스크립트를 사용하여 파일의 서로 다른 결과를 작성하려는 경우

db.runCommand({ 
    "distinct": "collection", 
    "query": { 
     "columnA": { 
      "$gt": 5 
     } 
    }, 
    "key": "columnA" 
}); 
2

...이 방법을이다

cursor = db.myColl.find({'fieldName':'fieldValue'}) 

var Arr = new Array(); 
var count = 0; 

cursor.forEach(

function(x) { 

    var temp = x.id;  
var index = Arr.indexOf(temp);  
if(index==-1) 
    { 
    printjson(x.id); 
    Arr[count] = temp; 
     count++; 
    } 
}) 
4

을 당신이

공처럼 총을 사용할 수 있다고 생각합니다
collection.aggregate({ 
    $group : { 
     "_id" : "$id", 
     "docs" : { 
      $first : { 
      "name" : "$name", 
      "ttm" : "$ttm", 
      "val" : "$val", 
      } 
     } 
    } 
}); 
11

집합을 사용하려고합니다. 이 같은 것을 할 수있는이 매우 빠른 100,000 문서 내 테스트 DB 용 ~ 90ms의 될 것

db.test.aggregate([ 
    // each Object is an aggregation. 
    { 
     $group: { 
      originalId: {$first: '$_id'}, // Hold onto original ID. 
      _id: '$id', // Set the unique identifier 
      val: {$first: '$val'}, 
      name: {$first: '$name'}, 
      ttm: {$first: '$ttm'} 
     } 

    }, { 
     // this receives the output from the first aggregation. 
     // So the (originally) non-unique 'id' field is now 
     // present as the _id field. We want to rename it. 
     $project:{ 
      _id : '$originalId', // Restore original ID. 

      id : '$_id', // 
      val : '$val', 
      name: '$name', 
      ttm : '$ttm' 
     } 
    } 
]) 

.

예 :

db.test.find() 
// { "_id" : ObjectId("55fb595b241fee91ac4cd881"), "id" : 1, "name" : "x", "ttm" : 23, "val" : 5 } 
// { "_id" : ObjectId("55fb596d241fee91ac4cd882"), "id" : 1, "name" : "x", "ttm" : 34, "val" : 1 } 
// { "_id" : ObjectId("55fb59c8241fee91ac4cd883"), "id" : 1, "name" : "x", "ttm" : 24, "val" : 2 } 
// { "_id" : ObjectId("55fb59d9241fee91ac4cd884"), "id" : 2, "name" : "x", "ttm" : 56, "val" : 3 } 
// { "_id" : ObjectId("55fb59e7241fee91ac4cd885"), "id" : 2, "name" : "x", "ttm" : 76, "val" : 3 } 
// { "_id" : ObjectId("55fb59f9241fee91ac4cd886"), "id" : 3, "name" : "x", "ttm" : 54, "val" : 7 } 


db.test.aggregate(/* from first code snippet */) 

// output 
{ 
    "result" : [ 
     { 
      "_id" : ObjectId("55fb59f9241fee91ac4cd886"), 
      "val" : 7, 
      "name" : "x", 
      "ttm" : 54, 
      "id" : 3 
     }, 
     { 
      "_id" : ObjectId("55fb59d9241fee91ac4cd884"), 
      "val" : 3, 
      "name" : "x", 
      "ttm" : 56, 
      "id" : 2 
     }, 
     { 
      "_id" : ObjectId("55fb595b241fee91ac4cd881"), 
      "val" : 5, 
      "name" : "x", 
      "ttm" : 23, 
      "id" : 1 
     } 
    ], 
    "ok" : 1 
} 

장점 : 거의 확실하게 빠른 방법.

단점 : 복잡한 집계 API 사용과 관련됩니다. 또한 문서의 원래 스키마와 밀접하게 연결되어 있습니다. 그러나 이것을 일반화하는 것이 가능할 수도 있습니다.