사붐이개발일기
mongoDB 3일차 (cursor, indexing) 본문
커서 (cursor)
- 테이블에서 여러 개의 행을 쿼리한 후에, 쿼리의 결과인 행 집합을 한 행씩 처리하기 위한 방식
- 커서의 초기값은 첫 번째 행 이전을 가리킴
- next()를 이용하여 다음 행으로 이동하여 해당 행의 값을 반환
for(i=0; i<100; i++){
db.foo.insertOne({x : i})
}
var cursor = db.foo.find();
while(cursor.hasNext()){
obj = cursor.next();
print(obj.x); // 0부터 99까지 콘솔에 출력
}
인덱싱 (indexing)
- Query를 더욱 효율적으로 할 수 있도록 documents에 기준(key)을 정해 정렬된 목록을 생성하는 것
- 인덱스가 없으면 쿼리 조건에 맞는 도큐먼트를 조회하기 위해 collection scan(컬렉션의 도큐먼트를 처음부터 끝까지 조회)을 실행
- 몽고디비 인덱스
- db의 검색을 빠르게 하기 위하여 데이터 순서를 미리 정해두눈 과정
- 고정된 스키마는 없지만, 원하는 필드를 인덱스로 지정하여 검색 결과를 빠르게 함
- index는 한 쿼리에 한 개의 index만 유효함 → 두 개의 index가 필요하다면 복합 index를 사용
- index는 어떤 데이터가 도큐먼트에 추가되거나 수정될 때(write 작업) 그 컬렉션에 생성되어 있는 index도 새로운 도큐먼트를 포함시켜 수정됨 → index 추가 시 write작업은 느려질 수 있음 -> index는 read 작업 위주의 애플레케이션에서 유용하고 읽기보다 쓰기 작업이 많으면 index를 생성하는것은 비효율적임
- _id 인덱스
- 컬렉션을 생성하는 동안 _id필드에 고유한 인덱스를 생성
- _id 필드에 같은 값을 가진 2개의 도큐먼트를 삽입할수 없도록 함
- _id필드의 인덱스를 제거할 수 없음
- 인덱스 생성하기
- db.collection.createIndex(<key and index type specification>, <options>)
- 인덱스의 기본 이름
- 인덱스의 키와 방향(오름차순, 내림차순)의 조합
- 예: {item: 1, quantity: -1}에 생성된 이름 item_1_quantity_-1
- 인덱스 속도 측정하기
- db.collection명.find({조건}).explain("executionStats").executionStats.executionTimeMillis
- 인덱싱 규칙
- 인덱스는 document를 가져오기 위해 필요한 작업량을 줄임
- 한 쿼리를 실행하기 위해서 하나의 인덱스만 사용 할 수 있음 ($or 연산자 사용시 제외, 버전 별로 다를 수 있음) →복합 키를 사용하는 쿼리에 대해서는 복합 인덱스가 적합함
- 복합 인덱스에서 키의 순서는 중요함
- 인덱스는 모든 값을 정렬된 순서로 보관하므로 인덱스 키로 도큐먼트를 정렬하는 작업에 용이
- 단일 필드 인덱스 (single field index)
- db.users.createIndex({ score: 1 }) // 오름차순
- 복합 인덱스 (compound index)
- db.collection명.createIndex( { <field1>: <type1>, <field2>: <type2>, ... } )
- 두 개 이상의 필드를 사용하는 인덱스, 순서가 중요함

- 인덱스 조회
- db.users.getIndexes()

- 특정 인덱스 삭제
- db.users.dropIndex("age_1_username_-1")
- 모든 인덱스 삭제 : _id 관련 인덱스를 제외한 모든 인덱스 삭제
- db.users.dropIndexes()
텍스트 인덱스
- 제목, 설명 등 컬렉션 내에 있는 필드의 텍스트와 일치시키는 키워드 검색에 사용
db.stores.insertMany(
[
{_id: 1, name: "Java Hut", description: "Coffee and cakes" },
{_id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
{_id: 3, name: "Coffee Shop", description: "Just coffee" },
{_id: 4, name: "Clothes Clothes Clothes", description: "Discount clothing" },
{_id: 5, name: "Java Shopping", description: "Indonesian goods"}
]
)
db.stores.find({"name": {"$regex": "Sh.*"}}) // 인덱스 없이 find()

- "name"필드에 text 인덱스 생성
- db.stores.createIndex({ "name": "text" })
- "name"필드에 해당하는 값이 java, coffee, shop이 포함된 문자열 검색
- db.stores.find({ "$text": { "$search": "java coffee shop" } })

- "name"필드에 해당하는 값이 java shop이 포함된 문자열 검색
- db.stores.find({ "$text": { "$search": '\"java shop\"' } })
- db.stores.find({ "$text": { "$search": "coffee", "$caseSenitive" } }) // 대소문자 일치 여부 확인
'Database > MongoDB' 카테고리의 다른 글
| mongoDB 4일차 (공간정보 GeoJSON) (1) | 2023.02.08 |
|---|---|
| 공공데이터(json)으로 인덱싱하기 (0) | 2023.02.07 |
| SQL vs mongoDB (용어 및 예제) (0) | 2023.02.07 |
| mongoDB 2일차 (CRUD) (0) | 2023.02.07 |
| mongoDB 와 Python 연동 (동적 웹크롤링) (0) | 2023.02.06 |