ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MongoDB - index (2)
    mongoDB 2022. 5. 29. 18:49

    2022.04.17 - [mongoDB] - MongoDB - index (1) 에 이어서 작성하도록 하겠다.

    Index properties

     index에는 여러 property들이 있는데 이에 대해 간단하게 설명하도록 하겠다.


    TTL Indexes

    정해진 시간 이후에 자동으로 document를 지울 때 사용하는 index이다. (만약 timeseries collection을 사용한다면 index가 아닌 collection의 option에 expireAfterSeconds를 추가해야한다.) 

    db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )

    Replica Set의 경우에는 TTL background thread가 primary DB에서만 동작하고, Secondary는 primary에 의해 삭제된다.


    Unique Indexes

     중복된 정보를 저장하지 않도록 막는 index이다. 이는 single field, compound 두가지 모두 지원이 가능하다.

    db.members.createIndex( { "user_id": 1 }, { unique: true } )

    User_id라는 field의 값은 unique 해야 한다.

    db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )

    GroupNumber, lastname, firstname 각각은 unique하지 않아도 되나 groupNumber_lastname_firstname이 세 값을 동일하게 갖는 document는 unique해야 한다.

     만약 해당 index가 적용되는 key가 없을 경우 null로 저장되고 이 또한 중복이 허용되지 않기 때문에 unique 하게 된다. 위의 예에서 user_id가 없는 document는 user_id:null로 저장되고 unique하다.


    Partial Indexes

     인덱스를 collection 전체 영역이 아닌 특정 영역에 대해서 생성할 수 있다.

    db.restaurants.createIndex(
       { cuisine: 1, name: 1 },
       { partialFilterExpression: { rating: { $gt: 5 } } }
    )

    여기서 partial index는 unique index와 함께 사용할 수 있으므로 아까 unique index에서 문제가 되었던 user_id가 없는 경우를 아래와 같이 해결할 수 있다.

    db.members.createIndex(
       { user_id: 1 },
       { unique: true, partialFilterExpression: { user_id: { $exists: true } } }
    )

    Case Insensitive Indexes

     Query 사용 시 upperCase, lowerCase에 상관 없도록 지원할 수 있다.

    db.createCollection("fruit")
    
    db.fruit.createIndex( { type: 1},
                          { collation: { locale: 'en', strength: 2 } } )
                          
    db.fruit.insertMany( [
       { type: "apple" },
       { type: "Apple" },
       { type: "APPLE" }
    ] )
    
    db.fruit.find( { type: "apple" } ) // does not use index, finds one result
    
    db.fruit.find( { type: "apple" } ).collation( { locale: 'en', strength: 2 } )
    // uses the index, finds three results
    
    db.fruit.find( { type: "apple" } ).collation( { locale: 'en', strength: 1 } )
    // does not use the index, finds three results

    Hidden Indexes

     Query planner로도 확인할 수 없고 query를 지원할 수도 없는 index이다. 이는 index를 drop하는 대신 hide하는 용도로 사용한다. 다시 unhide시킬 수 있다.

    db.restaurants.createIndex( { borough: 1, ratings: 1 } );
    # 3, 4 line is same operation
    db.restaurants.hideIndex( { borough: 1, ratings: 1 } ); // Specify the index key specification document
    db.restaurants.hideIndex( "borough_1_ratings_1" );  // Specify the index name
    # 6, 7 line is same operation
    db.restaurants.unhideIndex( { borough: 1, city: 1 } );  // Specify the index key specification document
    db.restaurants.unhideIndex( "borough_1_ratings_1" );    // Specify the index name

    Sparse Indexes

     Index에 해당하는 값이 존재하지 않을 때 이를 스킵한다. ({"Key":Null}은 값으로 스킵하지 않는다)

    # in score collection
    { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
    
    db.scores.createIndex( { score: 1 } , { sparse: true } )
    
    db.scores.find( { score: { $lt: 90 } } )
    #result of find
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

    Socre가 sparse 이므로 찾을 때 없으면 찾지 않는다.

     

    Sparse Index를 정확하게 사용하기 위해서는 hint()를 사용해서 어떤 index를 사용할 지 지정해 줘야 한다.

    #data
    { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
    
    db.scores.find().sort( { score: -1 } )
    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
    { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
    
    db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )
    #result hint로 index를 지정하면 score가 없는 data를 가져오지 않는다.
    { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
    { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

     

     

    'mongoDB' 카테고리의 다른 글

    mongoDB에서 data history 관리하기  (0) 2022.07.31
    MongoDB Version up에서 발생한 추가 문제사항  (0) 2022.06.06
    MongoDB - index (1)  (0) 2022.04.17
    MongoDB - Data modeling (2)  (0) 2022.04.16
    MongoDB - Data modeling (1)  (0) 2022.04.14

    댓글

Designed by Tistory.