사붐이개발일기

mongoDB 3일차 (cursor, indexing) 본문

Database/MongoDB

mongoDB 3일차 (cursor, indexing)

sabeom 2023. 2. 7. 15:54

커서 (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" } })    // 대소문자 일치 여부 확인