2012-09-25 4 views
0

다음 상황에 대한 전문 지식이 필요합니다.가장 일치하는 요소로 MongoDB 배열 및 정렬 쿼리

"array" : { 
    "item" : 1, 
    "1" : [100, 130, 255], 
} 

"array" : { 
    "item" : 2, 
    "1" " [0, 70, 120], 
} 

"array" : { 
    "item" : 3, 
    "1" : [100, 90, 140], 

} 

나는 등이 컬렉션을 쿼리하고있다 :이 나에게 항목 번호 1과 3을 반환

db.test.find(array.1 : {$in : [100, 80, 140]}); 

가 제공 배열의 모든 값을 일치하기 때문에

나는 등의 컬렉션이 있습니다 컬렉션에있는 것들과. 그러나 좀 더 비슷한 숫자의 결과를 얻기 위해이 배열을 정렬하고 싶습니다. 결과는 항목 3과 항목 1이어야합니다.

그러나 결과를 잡고 k- 가장 가까운 이웃 알고리즘을 사용하여 배열을 정렬 할 수 있습니다. 그러나 거대한 데이터 세트를 다루는 것은 매우 바람직하지 않습니다. (또는 그럴까요?) MongoDB 내에 어떤 기능이 있습니까? 자바를 사용하고 있는데,이 알고리즘을 충분히 빠르게 구현하려면 어떤 알고리즘이 필요합니까? 도움을 주시면 감사하겠습니다.

감사합니다.

답변

5

쉬운 일은 아니지만 집계 프레임 워크에서이를 수행 할 수 있습니다. 문제는 집계 프레임 워크의 일부로 $in 연산자가 없다는 것입니다. 따라서 배열의 각 항목을 프로그래밍 방식으로 일치시켜야하므로 매우 혼란 스럽습니다. 편집 : 일치가 첫 번째가되도록 재정렬하여 $in이 좋은 부분을 필터링하는 데 도움이됩니다.

db.test.aggregate(
    {$match:{"array.1":{$in:[100, 140,80]}}}, // filter to the ones that match 
    {$unwind:"$array.1"}, // unwinds the array so we can match the items individually 
    {$group: { // groups the array back, but adds a count for the number of matches 
    _id:"$_id", 
    matches:{ 
     $sum:{ 
     $cond:[ 
      {$eq:["$array.1", 100]}, 
      1, 
      {$cond:[ 
      {$eq:["$array.1", 140]}, 
      1, 
      {$cond:[ 
       {$eq:["$array.1", 80]}, 
       1, 
       0 
       ] 
      } 
      ] 
      } 
      ] 
     } 
     }, 
    item:{$first:"$array.item"}, 
    "1":{$push:"$array.1"} 
    } 
    }, 
    {$sort:{matches:-1}}, // sorts by the number of matches descending 
    {$project:{matches:1, array:{item:"$item", 1:"$1"}}} // rebuilds the original structure 
); 

출력은 : 당신이 마지막에 $project 밖으로두면

{ 
"result" : [ 
    { 
     "_id" : ObjectId("50614c02162d92b4fbfa4448"), 
     "matches" : 2, 
     "array" : { 
      "item" : 3, 
      "1" : [ 
       100, 
       90, 
       140 
      ] 
     } 
    }, 
    { 
     "_id" : ObjectId("50614bb2162d92b4fbfa4446"), 
     "matches" : 1, 
     "array" : { 
      "item" : 1, 
      "1" : [ 
       100, 
       130, 
       255 
      ] 
     } 
    } 
], 
"ok" : 1 
} 

당신은 결과의 밖으로 matches 필드를 남길 수 있습니다.

+0

+1 - Aggregation Framework의 사용법이 좋습니다. :) – Stennie

+0

안녕하세요, 감사합니다. @Stennie - 아마도 $ cond' 표현식에 '$ in'기능을 요청해야합니다. 이것은 훨씬 더 깨끗합니다! –

+0

아직 '$ in'에 대한 요청이 보이지 않으므로 추가하십시오. – Stennie