2010-12-05 5 views
8

각 문서의 배열이 memberslists 컬렉션이 있습니다. members 배열의 각 요소는 email 속성, 생성 date 속성 및 기타 일부 메타가있는 문서입니다. members.email에 동일한 색인을 두 번 입력하면 동일한 이메일이 두 번 입력되는 것을 방지하기 위해 고유 색인을 가지고 있지만 원래 date 값을 유지하고 싶습니다. 죄송 합니다만 $addToSet도 아니고 $push도 아닙니다. $ 푸시를 사용

예 :

$lists->update(array('_id' => $list['_id'], 'members.email' => array('$ne' => $email)), array('$push' => array('members' => array(
    'email' => $email, 
    'date' => new MongoDate(), 
    // etc. 
)))); 

그리고 $ addToSet와

:

$lists->update(array('_id' => $list['_id']), array('$addToSet' => array('members' => array(
    'email' => $email, 
    'date' => new MongoDate(), 
    // etc. 
)))); 

두 예제 인해 고유 date 값 (I 가정)에 새로운 하나를 전체 포함 된 문서를 대체합니다. members.email이 아직 없거나 두 명령에서이 작업을 수행해야하는 경우에만 $push "구성원"문서 만 가능합니까?

membersparent_list과 같은 속성으로 자신의 컬렉션에 넣는 것이 더 좋을까요?

답변

1

왜 list_id, email, added_date를 저장하는 컬렉션이 없습니까? 다음 두 개의 키 list_id와 전자 메일에 대해 고유 한 인덱스를 만듭니다. 그것은 삽입을 막을 것입니다 같은 list_id와 이메일 주소

임베디드 문서가 없습니다. list_id로 find()를 계속 사용할 수 있습니다.

0

예 가능합니다. mongoDB advanced queries 섹션에서 $ exists 연산자를 확인하십시오. $ exists 조건을 where 문에 코딩하여 멤버 전자 메일이 없을 때만 업데이트합니다.

+1

는 거의 긍정적 인 $은 내가 찾고 해결책 아니다 존재입니다. – Kevin

5

"$ push"또는 "$ addToSet"할 수없는 이유는 대상 "구성원"이 아마도 포함 된 개체 (또는 생성 후 변환 된 개체) 일 가능성이 있기 때문입니다. 당신은 $ push, $ pushAll, $ addToSet 임베디드 배열에만 사용할 수 있습니다 ...

불행히도 우리를 위해 불행히도 PHP 개발자 커서 쿼리는 항상 "회원"과 같은 경우 확인하는 가장 좋은 방법은 배열로 데이터를 반환합니다. 배열이나 객체 인 경우 mongo 쉘에서 find()를 실행하고 결과에서 중괄호 ("{}"또는 "[]")를 찾으십시오.

희망이 도움이됩니다.

0

IIUC, Upsert을 사용하여 포함 된 문서 (있는 경우)를 업데이트하거나 삽입하지 않은 경우 삽입하십시오. this도 참조하십시오.

확장성에 관한 두 번째 질문에 대해서는 부모에게 문서를 퍼가기 위해서는 더 많은 업데이트와 더 큰 데이터 가져 오기가 필요하지만 가져 오기 쿼리 수는 줄어 듭니다. 동일한 이메일의 회원들과 문서를 필터링하는 쿼리 condiction에서

1

사용 $ne :

$lists->update(array('_id' => $list['_id'], 
        'members.email' => array('$ne' => $email)), 
       array('$addToSet' => array('members' => array(
        'email' => $email, 
        'date' => new MongoDate(), 
         // etc. 
)))); 
관련 문제