2016-07-30 4 views
0

일부 MongoDB 쿼리가 작동하지 않습니다. 내 응용 프로그램에서 스레드와 메시지를 관리하는 간단한 구조가 있습니다.읽지 않은 메시지 쿼리

{ 
    participants: [ 
    'u1,'u2' 
    ] 
    messages: [ 
    {text: 'some message', readBy: ['u1','u2']} 
    {text: 'some other message', readBy: ['u1']} 
    ] 
} 

'U2'나는 쿼리에서 반환이 특정 스레드를 좀하고 싶습니다된다. 이것은 내가 어디까지 왔는지 알 수 있지만, 하나의 메시지가 'u2'에 의해 읽히 자마자 메시지 중 하나가 'u2'에 의해 읽혀질 때 더 이상 반환되지 않습니다.

Threads.find(
     { 
      $and: [ 
       {'participants': this.userId}, 
       {'messages.readBy': {$nin: [this.userId]}}   
      ] 
     }    
    ) 

데이터 구조를 변경하지 않고 어떻게이 작업을 수행 할 수 있습니까?

+0

가 예상 무엇입니까 당신 조회의 결과? – styvane

+0

결국 읽지 않은 모든 스레드를 계산해야합니다. 즉, 읽지 않은 메시지가 적어도 하나있는 스레드를 선택해야합니다. 이 정보를 사용하여 웹 페이지에 배지를 표시하므로 읽지 않은 메시지가 있음을 알 수 있습니다. SQL에서부터 나는 비정규 화 된 것들을 저장하지 않아서 주어진 구조로 끝났습니다. Meteor를 사용하고 있다는 점에 유의해야합니다. MongoDB가 지원하는 것은 모두 지원되며 반응이 없습니다. – chris1069603

+0

당신이 수락 한 대답이 효과가 있다면, 이것을하는 더 좋은 방법이 있습니다. – styvane

답변

0

aggregation을 사용하여 messages 배열을 Json 개체로 변형하는 $unwind 작업을 수행하면 필요한 항목을 정확히 요청하는 데 도움이됩니다.

다음 쿼리는 당신에게 "U2"는 "U2"읽을뿐만 아니라 메시지와 함께 참여 레코드를 줄 것이다 :

db.threads.aggregate([{ 
    $unwind: "$messages" 
}, { 
    $match: { 
     "participants": "u2", 
     "messages.readBy": { 
      $nin: ["u2"] 
     } 
    } 
}]); 

이 당신에게 줄 것이다 :

{ 
    "_id": ObjectId("579d0fc8733ac30906524be4"), 
    "participants": ["u1", "u2"], 
    "messages": { 
     "text": "some other message", 
     "readBy": ["u1"] 
    } 
} 
+0

이전에 집계를 사용한 적이 없다는 것을 인정해야합니다. 유능한 답변을 주셔서 대단히 감사합니다. 데이터 구조를 변경하지 말 것을 요청했지만 readBy를 무효화하면 (즉, unreadBy를 사용하면) 정상적인 쿼리를 사용할 수있게 될 것입니다. 집계를 사용 하시겠습니까? 아니면 정기적 인 쿼리를 사용할 수 있도록 일반적으로 데이터 구조를 변경하는 것이 더 좋습니까? – chris1069603

+0

은 귀하에게 달려 있습니다. 'find' 요청을 사용한다면, 집계를 사용하는 반면에, 당신의 취향에 따라 결과를 파싱해야 할 것입니다. mongoDB 엔진은 당신을 위해 그것을합니다. 집계는 좀 더 오래 걸릴 것이지만 필드, 프로젝트 등을 그룹화하고 작성할 수 있습니다. 집계를 사용하면 모든 새로운 메시지를 읽지 않은 상태로 하나의 배열을 가질 수있는 반면에 '찾기'를 통해 반복해야합니다 결과 및 직접이 배열을 빌드하십시오. –

관련 문제