code

Mongoose 채우기 대 개체 중첩

starcafe 2023. 5. 3. 21:35
반응형

Mongoose 채우기 대 개체 중첩

Mongoose 인구 사용과 직접 객체 포함 사이에 성능 차이(쿼리 처리 시간)가 있습니까?각각은 언제 사용해야 합니까?

몽구스 개체군 예:

var personSchema = Schema({
  _id     : Number,
  name    : String,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
});

Mongoose 개체 중첩 예제:

var personSchema = Schema({
  _id     : Number,
  name    : String,
  stories : [storySchema]
});

var storySchema = Schema({
  _creator : personSchema,
  title    : String,
});

몽구스 개체군에 대해 가장 먼저 이해해야 할 것은 그것이 마술이 아니라 단지 당신이 모든 것을 하지 않고 관련 정보를 검색할 수 있는 편리한 방법이라는 것입니다.

이 개념은 기본적으로 데이터를 내장하는 대신 별도의 컬렉션에 데이터를 배치해야 한다고 결정하는 경우에 사용되며, 주요 고려 사항은 일반적으로 문서 크기 또는 내장된 데이터를 유지하기 어려운 관련 정보가 자주 업데이트되는 경우에 사용되어야 합니다.

"마법이 아닌" 부분은 기본적으로 커버 아래에서 발생하는 것은 다른 소스를 "참조"할 때 채우기 함수가 검색한 상위 개체의 결과를 "병합"하기 위해 해당 "관련된" 컬렉션에 추가 쿼리/쿼리를 만든다는 것입니다.사용자가 직접 이 작업을 수행할 수 있지만, 작업을 단순화하기 위한 편리한 방법이 있습니다.분명한 "성능" 고려사항은 모든 정보를 검색하기 위해 데이터베이스(MongoDB 인스턴스)에 대한 왕복이 단 한 번도 없다는 것입니다.항상 하나 이상이 있습니다.

샘플로 두 개의 컬렉션을 선택합니다.

{ 
    "_id": ObjectId("5392fea00ff066b7d533a765"),
    "customerName": "Bill",
    "items": [
        ObjectId("5392fee10ff066b7d533a766"),
        ObjectId("5392fefe0ff066b7d533a767")
    ]
}

항목:

{ "_id": ObjectId("5392fee10ff066b7d533a766"), "prod": "ABC", "qty": 1 }
{ "_id": ObjectId("5392fefe0ff066b7d533a767"), "prod": "XYZ", "qty": 2 }

"참조" 모델 또는 채우기(후드 아래)를 사용하여 수행할 수 있는 "최상의" 방법은 다음과 같습니다.

var order = db.orders.findOne({ "_id": ObjectId("5392fea00ff066b7d533a765") });
order.items = db.items.find({ "_id": { "$in": order.items } ).toArray();

따라서 해당 데이터를 "결합"하기 위해 "적어도" 두 개의 쿼리와 작업이 분명히 존재합니다.

임베딩 개념은 본질적으로 "join"1을 지원하지 않는 방법에 대한 MongoDB의 답변입니다.따라서 데이터를 정규화된 컬렉션으로 분할하는 대신 "관련" 데이터를 사용하는 문서에 직접 포함하려고 합니다.여기서의 장점은 "관련" 정보를 검색하기 위한 단일 "읽기" 작업과 "상위" 및 "하위" 항목을 모두 업데이트하기 위한 단일 "쓰기" 작업이 있다는 것입니다.클라이언트의 "목록"을 처리하거나 "복수" 쓰기 작업을 수락하지 않고는 한 번에 "많은" 자녀에게 쓰기가 불가능한 경우가 종종 있지만, 가급적이면 "여러" 쓰기 작업을 수락하는 것이 좋습니다.

따라서 데이터는 위의 예와 비교하여 다음과 같이 나타납니다.

{ 
    "_id": ObjectId("5392fea00ff066b7d533a765"),
    "customerName": "Bill",
    "items": [
        { "_id": ObjectId("5392fee10ff066b7d533a766"), "prod": "ABC", "qty": 1 },
        { "_id": ObjectId("5392fefe0ff066b7d533a767"), "prod": "XYZ", "qty": 2 }
    ]
}

따라서 실제로 데이터를 가져오는 것은 다음과 같은 문제일 뿐입니다.

db.orders.findOne({ "_id": ObjectId("5392fea00ff066b7d533a765") });

둘 중 하나의 장단점은 항상 응용프로그램의 사용 패턴에 따라 크게 달라집니다.하지만 한눈에 보기:

임베딩

  • 내장된 데이터가 포함된 총 문서 크기는 일반적으로 16MB 스토리지(BSON 제한)를 초과하지 않으며, 그렇지 않으면 (지침으로) 500개 이상의 항목이 포함된 어레이가 있습니다.

  • 내장된 데이터는 일반적으로 자주 변경할 필요가 없습니다.따라서 비정규화로 인해 발생하는 "중복"으로 인해 많은 상위 문서에서 동일한 정보로 "중복"을 업데이트할 필요가 없습니다.

  • 관련 데이터는 상위 데이터와 관련하여 자주 사용됩니다.즉, "읽기/쓰기" 사례가 거의 항상 부모와 자식 모두에게 "읽기/쓰기"해야 하는 경우 원자력 운영을 위해 데이터를 포함하는 것이 타당합니다.

참조

  • 관련 데이터는 항상 16MB BSON 제한을 초과합니다."버킷팅"의 하이브리드 접근 방식을 항상 고려할 수 있지만, 기본 문서의 일반적인 하드 한계를 위반할 수는 없습니다.일반적인 경우는 "댓글" 활동이 매우 클 것으로 예상되는 "포스트" 및 "댓글"입니다.

  • 관련 데이터는 정기적으로 업데이트해야 합니다.또는 기본적으로 데이터가 많은 부모들 사이에서 "공유"되고 "관련" 데이터가 충분히 자주 변경되어 "자녀" 항목이 발생하는 모든 "부모"의 내장된 항목을 업데이트하는 것은 비현실적일 수 있기 때문에 "정상화"하는 경우입니다.더 쉬운 경우는 "아이"를 참조하여 한 번 변경하는 것입니다.

  • 읽기와 쓰기가 명확하게 구분됩니다."부모"를 읽을 때 항상 "관련" 정보를 요구하지 않거나 자녀에게 편지를 쓸 때 항상 "부모"를 변경할 필요가 없는 경우에는 참조된 대로 모델을 분리해야 할 충분한 이유가 있을 수 있습니다.또한, "하위 문서"가 실제로 다른 컬렉션을 참조하는 많은 "하위 문서"를 한 번에 업데이트하려는 일반적인 욕구가 있는 경우, 데이터가 별도의 컬렉션에 있을 때 구현하는 것이 훨씬 효율적입니다.

따라서 실제로 데이터 모델링에 대한 MongoDB 문서에서 "찬성/반대"에 대한 논의가 훨씬 더 광범위합니다. 이 문서에서는 다양한 사용 사례와 채우기 방법 또는 참조 모델을 사용하여 접근하는 방법을 다룹니다.

"점점"이 유용하기를 바라지만 일반적으로 애플리케이션의 데이터 사용 패턴을 고려하여 가장 적합한 것을 선택하는 것이 좋습니다.MongoDB를 "해야 한다"는 "옵션"을 갖는 것이 MongoDB를 선택한 이유이지만, 실제로 어떤 방법이 데이터 모델링의 어느 부분에 가장 적합한지 결정하는 것은 애플리케이션이 "데이터를 사용하는" 방식일 것입니다.

  1. MongoDB는 원래 이 문서가 작성되었기 때문에 서버의 컬렉션 간에 "join"을 실제로 수행하는 연산자를 소개했습니다.여기서 일반적인 논의를 위해, "다중 쿼리" 오버헤드가 발생하는 대부분의 상황에서 "더 나은" 휘파람을 불십시오.populate()그리고 일반적으로 "다중 쿼리"는 모든 작업에서 발생하는 "중대한 오버헤드"가 여전히 존재합니다.

핵심 설계 원칙은 "다른 곳에서 가져오기"와는 반대로 "이미"라는 의미입니다.기본적으로 "주머니 속"과 "책상에 있는" 사이의 차이이며, I/O 측면에서는 대개 "시내 도서관의 책꽂이에 있는" 것과 비슷하며, 특히 네트워크 기반 요청의 경우 훨씬 더 멀리 떨어져 있습니다.

언급URL : https://stackoverflow.com/questions/24096546/mongoose-populate-vs-object-nesting

반응형