커서를 사용하여 데이터 액세스
개요
이 가이드에서는 Rust 드라이버를 사용하여 커서 를 사용하여 읽기 작업 또는 애그리게이션에서 반환된 데이터에 액세스하는 방법을 배울 수 있습니다. 커서는 주어진 시간에 문서의 하위 집합만 메모리에 유지하면서 문서를 반복할 수 있는 메커니즘입니다.
드라이버는 커서에서 문서를 검색하기 위해 Cursor
유형을 제공합니다. 예를 들어, 여러 문서를 반환할 수 있는 찾기 작업을 실행하면 드라이버는 일치하는 문서에 액세스할 수 있는 Cursor
인스턴스를 반환합니다.
읽기 작업 또는 애그리게이션을 실행한 후 반환된 Cursor
인스턴스에는 작업의 첫 번째 결과 배치가 포함됩니다. 커서를 반복할수록 서버는 더 많은 개별 결과를 반환합니다. 결과 배치의 끝에 도달한 후 일치하는 문서가 더 있는 경우 Cursor
인스턴스는 모든 결과가 반환될 때까지 다음 문서 배치를 가져옵니다.
이 가이드에는 다음 섹션이 포함되어 있습니다.
예시용 샘플 데이터
이 가이드의 예제에서는 구조체에 저장된 다음 데이터를 사용합니다.
let docs = vec! [ Fruit { name: "strawberry".to_string(), color: "red".to_string() }, Fruit { name: "banana".to_string(), color: "yellow".to_string() }, Fruit { name: "pomegranate".to_string(), color: "red".to_string() }, Fruit { name: "pineapple".to_string(), color: "yellow".to_string() } ];
문서 개별 조회
드라이버는 Cursor
인스턴스에서 반환한 문서를 반복할 수 있도록 다음과 같은 액세스 패턴을 제공합니다.
내장 패턴: 커서를 앞으로 이동한 다음 현재 문서를 검색하고 역직렬화합니다.
스트림 구현 패턴: 커서 를 반복하고
Stream
에서 제공하는 메서드를 호출하여 단일 또는 여러 문서를 프로세스 합니다.
다음 섹션에서는 이러한 액세스 패턴과 해당 방법에 대해 자세히 설명합니다.
내장 패턴
드라이버에 내장된 액세스 패턴을 사용하여 문서를 하나씩 검색하고 처리할 수 있습니다.
Cursor
유형에는 커서를 반복하고 문서에 개별적으로 액세스하는 advance()
및 deserialize_current()
메서드가 포함되어 있습니다.
로컬 버퍼가 모두 소진되면 advance()
메서드는 커서를 앞으로 이동하고 커서가 결과 배치의 끝에 도달할 때 발생하는 추가 결과를 요청하는 요청을 데이터베이스에 보냅니다. 커서가 결과 배치 끝에 도달할 때마다 다음 배치를 요청합니다. 커서는 반환할 일치하는 문서가 더 이상 없고 더 이상 사용할 수 없을 때 소진된 것입니다. advance()
메서드는 새 결과가 성공적으로 반환된 경우 true
결과를 반환하고, 커서가 닫힌 경우 false
결과를 반환합니다.
deserialize_current()
메서드는 커서 내의 현재 결과에 대한 참고를 반환하고 결과를 커서와 연결된 유형으로 역직렬화합니다. 유형을 지정하지 않는 한 이 메서드는 collection이 매개변수화되는 것과 동일한 유형을 사용합니다.
중요
advance()
메서드가 true
결과를 반환하는 경우에만 deserialize_current()
메서드를 호출할 수 있습니다. true
결과 없이 또는 이전에 advance()
호출하지 않고 커서에서 deserialize_current()
를 호출하면 드라이버는 오류를 생성합니다.
다음 예시에서는 이 액세스 패턴을 구현하여 fruits
collection에서 찾기 작업의 결과를 반복하는 방법을 보여 줍니다.
let mut cursor = my_coll.find(doc! { "color": "red" }).await?; while cursor.advance().await? { println!("{:?}", cursor.deserialize_current()?); }
Fruit { name: "strawberry", color: "red" } Fruit { name: "pomegranate", color: "red" }
스트림 구현 패턴
커서 결과에 스트림으로 액세스하여 개별 문서를 검색하거나 한 번에 여러 문서를 수집할 수 있습니다.
Cursor
유형은 Stream
특성을 구현하므로 커서를 스트림으로 반복할 수 있습니다. Stream
확장 특성 StreamExt
은 작업을 결합하고 코드를 통합하는 다양한 기능을 제공하므로 이 패턴을 사용하면 내장 패턴보다 더 간결한 코드를 작성할 수 있습니다.
다음 메서드를 사용하여 스트림 패턴을 사용할 수 있습니다.
next()
: 커서를 다음 결과로 이동하고Option<Result<T>>
유형을 반환합니다.try_next()
: 커서를 다음 결과로 이동하고Result<Option<T>>
유형을 반환합니다.
중요
스트림 패턴 메서드에 필요한 가져오기
next()
메서드를 사용하려면 StreamExt
트레이트를 가져와야 합니다. try_next()
메서드를 사용하려면 TryStreamExt
트레이트를 가져와야 합니다.
다음 예시에서는 두 개의 스트림 메서드를 구현하여 fruits
collection에서 찾기 작업의 결과를 반복하는 방법을 보여 줍니다.
let mut cursor = my_coll.find(doc! { "color": "red" }).await?; println!("Output from next() iteration:"); while let Some(doc) = cursor.next().await { println!("{:?}", doc?); } println!(); let mut cursor = my_coll.find(doc! { "color": "yellow" }).await?; println!("Output from try_next() iteration:"); while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Output from next() iteration: Fruit { name: "strawberry", color: "red" } Fruit { name: "pomegranate", color: "red" } Output from try_next() iteration: Fruit { name: "banana", color: "yellow" } Fruit { name: "pineapple", color: "yellow" }
문서를 배열로 조회
Cursor
유형은 Stream
특성을 구현하므로 커서에서 결과를 배열로 수집할 수 있습니다.
다음 메서드를 사용하여 문서를 배열로 조회할 수 있습니다.
collect()
: 커서의 결과를Vec<Result<T>>
유형으로 수집합니다.try_collect()
: 커서의 결과를Result<Vec<T>>
유형으로 수집합니다.
참고
collect()
메서드를 사용하려면 StreamExt
트레이트를 가져와야 합니다. try_collect()
메서드를 사용하려면 TryStreamExt
트레이트를 가져와야 합니다.
let cursor = my_coll.find(doc! { "color": "red" }).await?; println!("Output from collect():"); let v: Vec<Result<Fruit>> = cursor.collect().await; println!("{:?}", v); println!(); let cursor = my_coll.find(doc! { "color": "yellow" }).await?; println!("Output from try_collect():"); let v: Vec<Fruit> = cursor.try_collect().await?; println!("{:?}", v);
Output from collect(): [Ok(Fruit { name: "strawberry", color: "red" }), Ok(Fruit { name: "pomegranate", color: "red" })] Output from try_collect(): [Fruit { name: "banana", color: "yellow" }, Fruit { name: "pineapple", color: "yellow" }]
경고
애플리케이션 메모리 제한 초과 방지
많은 양의 결과 세트를 배열로 변환하지 마세요. 배열 이 사용 가능한 애플리케이션 메모리 크기를 초과하면 애플리케이션 이 충돌할 수 있습니다. 큰 결과 설정하다 가 예상되는 경우 커서 에서 문서를 개별적으로 조회 합니다. 커서 를 반복하는 방법을 학습 보려면 이 가이드 의 개별적으로 문서 조회 섹션을 참조하세요.
커서 동작 지정
작업에서 반환하는 커서 를 수정하려면 Cursor
인스턴스 를 반환하는 메서드에 옵션 빌더 메서드를 연결합니다. 예를 예시 커서 관련 옵션 빌더 메서드를 find()
메서드에 연결할 수 있습니다.
참고
설정 옵션
옵션 빌더 메서드를 find()
메서드 호출에 직접 연결하여 FindOptions
필드를 설정하다 수 있습니다. 이전 버전의 운전자 를 사용하는 경우 옵션 빌더 메서드를 builder()
메서드에 연결하여 FindOptions
인스턴스 를 구성해야 합니다. 그런 다음 FindOptions
인스턴스 를 find()
에 매개 변수로 전달합니다.
다음 표에서는 해당 빌더 메서드를 호출하여 설정하다 수 있는 커서 관련 옵션에 대해 설명합니다.
설정 | 설명 |
---|---|
| Specifies the maximum number of documents the server returns per
cursor batch. This option sets the number of documents the cursor
keeps in memory rather than the number of documents the cursor
returns. Type: u32 Default: 101 documents initially, 16 MB maximum for
subsequent batches |
| Specifies the type of cursor to return. You can set this option
to produce a tailable cursor. To learn more about tailable
cursors, see Tailable Cursors in the Server manual. Type: CursorType Default: CursorType::NonTailable |
| Specifies whether the server closes the cursor after a period
of inactivity. IMPORTANT:
Because the Cursor type implements the Drop trait, the
server closes a cursor when it goes out of scope. The server
runs an asynchronous killCursors command to close the
cursor. See killCursors
in the Server manual to learn more.Type: bool Default: false |
다음 코드는 옵션 빌더 메서드를 find()
메서드에 연결하여 커서 관련 설정을 지정하는 방법을 보여줍니다.
let mut cursor = my_coll.find(doc! { "color": "red" }) .batch_size(5) .cursor_type(CursorType::Tailable) .no_cursor_timeout(true) .await?;
추가 정보
이 가이드의 작업에 대해 자세히 알아보려면 다음 문서를 참조하세요.
Rust 유형과 BSON 간의 변환에 대해 자세히 알아보려면 데이터 모델링 및 직렬화 가이드를 참조하세요.
API 문서
이 가이드에서 사용되는 메서드 또는 유형에 대해 자세히 알아보려면 다음 API 문서를 참조하세요.
Next()
StreamExt
트레이트에서try_next()
TryStreamExt
트레이트에서collection()
StreamExt
트레이트에서try_collect()
TryStreamExt
트레이트에서