복붙노트

[MONGODB] MongoDB의 페이지 매김 원거리

MONGODB

MongoDB의 페이지 매김 원거리

많은 레코드 MongoDB의 컬렉션에서 페이지 매김에 대한 건너 뛰기 ()를 사용하는 것이 느리고하지 않는 것이 좋습니다했다입니다.

원거리 매김을 사용할 수 있습니다 (> _id comparsion 기준)

db.items.find({_id: {$gt: ObjectId('4f4a3ba2751e88780b000000')}});

그것은 이전을 표시 좋다. 및 다음 버튼 - 당신이있는 각 페이지의 시작 "_id"-계산을 사전에 필요 -하지만 당신이 실제 페이지 번호 1을 표시 할 때 5 6 7 ... 124 ... 구현하는 것은 매우 쉬운 일이 아닙니다.

나는이 개 질문이 그래서 :

1) 언제 그것에 대해 걱정을 시작해야합니까? 때 스킵에 띄게 둔화와 거기 "너무 많은 레코드"()? 1 000? 1 000 000?

2) 원거리 페이지 매김을 사용하는 경우 실제 페이지 번호 링크를 표시 할 수있는 가장 좋은 방법은 무엇입니까?

해결법

  1. ==============================

    1.좋은 질문!

    좋은 질문!

    "얼마나 많은 너무 많은입니까?" - 즉, 물론, 데이터 크기 및 성능 요구 사항에 따라 달라집니다. 내가 이상의 500-1000 기록을 건너 뛸 때 나는 개인적으로 불편.

    실제 대답은 사용자의 요구 사항에 따라 달라집니다. 여기에 (그들 중 일부는, 적어도, 나) 현대 사이트가하는 일입니다.

    첫째,이 같은 네비게이션 바에 외모 :

    1 2 3 ... 457
    

    그들은 총 레코드 수 및 페이지 크기에서 마지막 페이지 번호를 얻을. 첫 번째 레코드에서 일부 건너 뛰기를 포함 할 것이다 3 페이지에하자 점프. 결과가 도착하면, 당신은 3 페이지의 첫 번째 레코드의 ID를 알고있다.

    1 2 3 4 5 ... 457
    

    의 좀 더 건너 뛰고 5 페이지에 가자.

    1 ... 3 4 5 6 7 ... 457
    

    당신은 아이디어를 얻을. 각 시점에서 당신은 먼저 지난 현재 페이지를 참조하십시오, 또한이 페이지는 현재 페이지에서 앞뒤로.

    var current_id; // id of first record on current page.
    
    // go to page current+N
    db.collection.find({_id: {$gte: current_id}}).
                  skip(N * page_size).
                  limit(page_size).
                  sort({_id: 1});
    
    // go to page current-N
    // note that due to the nature of skipping back,
    // this query will get you records in reverse order 
    // (last records on the page being first in the resultset)
    // You should reverse them in the app.
    db.collection.find({_id: {$lt: current_id}}).
                  skip((N-1)*page_size).
                  limit(page_size).
                  sort({_id: -1});
    
  2. ==============================

    2.그것은 당신이 표시되고있는 결과 세트를 구성하기 위해 사용하고있는 쿼리 (또는 쿼리)에 많이 의존하기 때문에 일반적인 대답을하기 어렵다. 결과는 유일한 인덱스를 사용하여 발견 될 수 있고, 인덱스 순서로 제시 한 후 db.dataset.find (). 제한하는 경우 (). (가)에도 스킵 다수 잘 수행 할 수있는 이동. 이 가능성이 코드까지 가장 쉬운 방법입니다. 당신은 페이지 번호를 캐시 및 인덱스 값으로 묶을 수 있다면 심지어 경우에, 당신은 빠른 예를 들어,보기 71 페이지에 원하는 두 번째와 세 번째 사람을 위해 할 수 있습니다.

    그것은 당신이 표시되고있는 결과 세트를 구성하기 위해 사용하고있는 쿼리 (또는 쿼리)에 많이 의존하기 때문에 일반적인 대답을하기 어렵다. 결과는 유일한 인덱스를 사용하여 발견 될 수 있고, 인덱스 순서로 제시 한 후 db.dataset.find (). 제한하는 경우 (). (가)에도 스킵 다수 잘 수행 할 수있는 이동. 이 가능성이 코드까지 가장 쉬운 방법입니다. 당신은 페이지 번호를 캐시 및 인덱스 값으로 묶을 수 있다면 심지어 경우에, 당신은 빠른 예를 들어,보기 71 페이지에 원하는 두 번째와 세 번째 사람을 위해 할 수 있습니다.

    문서를 추가하고 다른 사람이 데이터를 통해 페이징하는 동안 제거됩니다 매우 동적 데이터 세트에서 캐싱 신속하고 한계의 최신 경우가 및 방법은 좋은 결과를 제공 할 수있는 하나의 신뢰할 수있는 충분한 수 있습니다 건너 뜁니다.

  3. ==============================

    3.예를 들어 "FIRSTNAME"독특한 아니었다 필드를 사용하는 동안 요청을 페이지를 매기려고 할 때 나는 최근에 같은 문제가 발생합니다. 이 쿼리의 아이디어는 건너 뛰기를 사용하지 않고 고유하지 않은 필드에 페이지 매김을 구현 할 수있다 ()

    예를 들어 "FIRSTNAME"독특한 아니었다 필드를 사용하는 동안 요청을 페이지를 매기려고 할 때 나는 최근에 같은 문제가 발생합니다. 이 쿼리의 아이디어는 건너 뛰기를 사용하지 않고 고유하지 않은 필드에 페이지 매김을 구현 할 수있다 ()

    여기에 주요 문제는 다음과 같은 일이 일어날 것이기 때문에 "FIRSTNAME '이 (가) 고유하지 않습니다 필드를 조회 할 수있는됩니다 :

    나는 그것을 고유 검색하게하기 위해 보조 필드 타겟을 검색 필드를 결합하여 독특한 쿼리의 $ 일치하는 부분을 만들고 있었다 내놓았다 따라서 솔루션입니다.

    순서를 오름차순 :

    db.customers.aggregate([
        {$match: { $or: [ {$and: [{'FirstName': 'Carlos'}, {'_id': {$gt: ObjectId("some-object-id")}}]}, {'FirstName': {$gt: 'Carlos'}}]}},
        {$sort: {'FirstName': 1, '_id': 1}},
        {$limit: 10}
        ])
    

    내림차순 :

    db.customers.aggregate([
        {$match: { $or: [ {$and: [{'FirstName': 'Carlos'}, {'_id': {$gt: ObjectId("some-object-id")}}]}, {'FirstName': {$lt: 'Carlos'}}]}},
        {$sort: {'FirstName': -1, '_id': 1}},
        {$limit: 10}
        ])
    

    이 쿼리의 $ 일치하는 부분은 기본적으로 if 문으로 행동한다 : firstName을이 "카를로스는"다음은이 ID보다 커야 할 필요가 firstName을이 "카를로스"동일하지 않은 경우 그것은 "카를로스"보다 클 필요

    단지 문제는 당신이 할 수있는 특정 페이지 번호로 이동합니다 (그것은 아마 코드 조작을 수행 할 수 있습니다)하지만 메모리와 처리를 많이 먹고있는 건너 뛸 사용하지 않고 고유하지 않은 필드 매김 내 문제를 해결 이외하지 전원 당신이 쿼리하는 어떤 데이터 세트의 끝으로 가져올 때.

  4. from https://stackoverflow.com/questions/9703319/mongodb-ranged-pagination by cc-by-sa and MIT license