레이블이 pagination인 게시물을 표시합니다. 모든 게시물 표시
레이블이 pagination인 게시물을 표시합니다. 모든 게시물 표시

mongodb find pagination

# mongodb collection 의 document 조회(find)시 pagination
    // document _id 다음 포맷으로 구성되어 있어, _id 크기비교로 범위를 탐색할 수 있다.
    // https://www.mongodb.com/docs/manual/reference/method/ObjectId/#objectid
    // A 4-byte timestamp + A 5-byte random value + A 3-byte incrementing counter
    // 가장 오래된 document 파악
    filter = bson.D{{Key: "number", Value: bson.D{{Key: "$gt", Value: 0}}}}
    docs = make([]samepleDoc1, 0)
    // 가장 오래된 document 부터 2개 문서 가져오기
    c.FindByPageSize(filter, &docs, 2)
    page := 0
    lastObjID := docs[len(docs)-1].ObjId
    PrintDoc(docs)
    page++
    fmt.Printf("lastObjID %v page %v\n", lastObjID, page)
    // 페이지당 2개 documents 로 계속 조회
    for len(docs) > 0 {
        lastObjID := docs[len(docs)-1].ObjId
        filter = bson.D{{Key: "_id", Value: bson.D{{Key: "$gt", Value: lastObjID}}}}
        docs = make([]samepleDoc1, 0)
        c.FindByPageSize(filter, &docs, 2)
        PrintDoc(docs)
        page++
        fmt.Printf("lastObjID %v page %v\n", lastObjID, page)
    }

# 조회시 위 설정한 objid(_id) 크기로 비교로 다음 document를 조회한다.
func (mc *MongoDBClient) FindByPageSize(filter interface{}, r interface{}, pageSize int) {
    // ascending sort by document _id
    opt1 := options.Find().SetSort(bson.D{{Key: "_id", Value: 1}}).SetLimit(int64(pageSize))
    cursor, err := mc.Client.Database("my_db").Collection("my_coll").Find(context.TODO(), filter, opt1)
    if err != nil {
        log.Println("failed to find document", err.Error())
    }
    defer cursor.Close(context.TODO())
    // decode each document into r
    if err := cursor.All(context.TODO(), r); err != nil {
        log.Println("failed to decode document", err.Error())
    }
    log.Println("---Find result---")
}

# 테스트 코드
# https://github.com/ysoftman/test_code/tree/master/mongodb_golang