2014-04-09 2 views
0

관계형 데이터베이스 (예 : 제품 유형)를 사용하여 모델링 및 확장하기 어려운 데이터 유형이 다릅니다.Mongodb에서 하위 목록을 어떻게 관리합니까?

Mongodb를 사용하여이 문제를 해결하고 싶습니다. 예 (I, 나는이 특정 제품을 사용할 아이디의의 관계 목록을 관리 할 필요가 저장하고있는 데이터 형은

http://docs.mongodb.org/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/

:

은 내가 MongoDB를 웹 사이트에서 문서를 참조하고 상점 위치 ID). 그들은 다음과 같은있다 "내장 된 문서와 일대 다 관계"에 대한 자신의 예에서

:

{ 
    name: "O'Reilly Media", 
    founded: 1980, 
    location: "CA", 
    books: [12346789, 234567890, ...] 
} 

나는 현재 스프레드 시트로 데이터를 가져 오기 및 batchInsert을 사용하고자하고있다.

1) 내가이 ID에 인덱스를 확인하고 삽입에 오류를 무시 할 필요가 : 중복을 방지하기 위해

, 나는 가정? 2) 그런 다음 새로운 ID를 책에 삽입하려면 모든 ID를 반복해야합니까?

+0

질문이 명확하지 않습니다. 정확히 무엇을 요구하고 있습니까? – Avish

답변

0

귀하의 질문을 조금 더 잘 정의 할 수는 있지만 스프레드 시트 나 다른 소스에 어떤 방식 으로든 모두 비정규 화 된 행이있는 경우를 생각해 봅시다. 행은 다음과 같이 될 것 JSON 표현에 그래서 :

{ 
    "publisher": "O'Reilly Media", 
    "founded": 1980, 
    "location": "CA", 
    "book": 12346789 
}, 
{ 
    "publisher": "O'Reilly Media", 
    "founded": 1980, 
    "location": "CA", 
    "book": 234567890 
} 

그래서 "upsert" 기능을 사용하는 것입니다 당신이 원하는 구조로이 작업을 수행하는 방법을 행 결과 그 종류를 얻기 위하여 .update() 방법 :

books.forEach(function(book) { 

    db.publishers.update(
     { 
      "name": book.publisher 
     }, 
     { 
      "$setOnInsert": { 
       "founded": book.founded, 
       "location": book.location, 
      }, 
      "$addToSet": { "books": book.book } 
     }, 
     { "upsert": true } 
    ); 

}) 
,536 :

그래서 당신이 입력 값을 루프의 몇 가지 방법이 그들이 다음이에 아날로그 식으로 뭔가를 할 것 몇 가지 구조로 식별됩니다 가정

이것은 기본적으로 코드를 단순화하여 MongoDB가 모든 데이터 수집 작업을 수행하도록합니다. 따라서 게시자의 "이름"이 고유 한 것으로 간주되는 곳에서 해당 문이 수행하는 작업은 먼저 "이름"으로 지정된 쿼리 조건과 일치하는 컬렉션의 문서를 검색하는 것입니다.

해당 문서가없는 경우 새 문서가 삽입됩니다. 따라서 데이터베이스 또는 드라이버가이 문서의 새로운 _id 값을 생성하고 "조건"이 존재해야하는 묵시적인 값이기 때문에 새 문서에 자동으로 삽입됩니다.

연산자 연산자를 사용하면 해당 필드는 새 문서가 만들어 질 때만 설정됩니다. 마지막 부분은 아직 발견되지 않은 서적 값을 "서적"배열 (또는 세트)에 "밀어 넣기"위해 $addToSet을 사용합니다.

분리 이유는 지정된 "게시자"이름으로 문서가 실제로 발견 된 경우입니다. 이 경우 $setOnInsert 아래의 모든 입력란은 문서에 이미 포함되어 있으므로 무시됩니다.따라서 $addToSet 작업 만 처리되어 "books"배열 (집합)에 새 항목을 추가하고 아직없는 위치에 추가됩니다.

그래서 새로운 삽입 작업을 보내기 전에 코드에서 새 레코드를 집계하는 것과 비교하면 논리가 단순 해집니다. 그러나 각 행에 대해 서버에 대해 일부 작업을 수행하는 것과 같이 매우 "일괄 처리"되는 것은 아닙니다.

이제 MongoDB 버전 2.6 이상에서는 "batch" updates을 수행 할 수 있으므로이 문제가 해결되었습니다.

var batch = []; 

books.forEach(function(book) { 

    batch.push({ 
     "q": { "name": book.publisher }, 
     "u": { 
      "$setOnInsert": { 
       "founded": book.founded, 
       "location": book.location, 
      }, 
      "$addToSet": { "books": book.book } 
     }, 
     "upsert": true 
    }); 

    if ((batch.length % 500) == 0) { 
     db.runCommand("update", "updates": batch); 
     batch = []; 
    } 
}); 

db.runCommand("update", "updates": batch); 

그래서 한 번이 경우, 일괄 전송 작업의 합리적인 크기의 서버에 하나의 호출로 구성된 업데이트 문을 모두 설정에서 무엇을하고 있는지마다 500 : 비슷한 아날로그와 그래서 처리 된 항목. 실제 제한은 BSON 문서 최대 16MB이므로 데이터에 맞게 변경할 수 있습니다.

MongoDB 버전이 2.6보다 낮은 경우 첫 번째 양식을 사용하거나 기존 배치 삽입 기능을 사용하여 두 번째 양식과 유사한 작업을 수행하십시오. 그러나 삽입을 선택하면 코드 내에서 모든 사전 집계 작업을 수행해야합니다.

물론 모든 방법은 PHP 드라이버에서 지원되므로 실제로이 코드를 실제 코드와 취향에 맞게 조정하면됩니다.