정환타 개발노트

MongoDB CRUD 사용(입력, 조회, 수정, 삭제) 본문

Dev-Database/NoSQL

MongoDB CRUD 사용(입력, 조회, 수정, 삭제)

JungHwanTa 2020. 2. 3. 17:09

MongoDB

mongodb에서 CRUD(Create, Read, Update, Delete)를 하는 방법에 대해 알아보려고 한다.

먼저, MongoDB의 설치는 하단의 링크를 참조하면 된다.

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/

 

MongoDB는 NoSQL이지만, 다른 RDBMS와 같이 CRUD를 제공하는데, 하나씩 살펴보겠다.

(글쓰는 시점 기준으로 가장 최신버전인 4.2를 기준으로 작성하였습니다.)

 

Create Operations(Insert)

Create는 새로운 documents를 collection에 생성하거나 추가하는 동작이다. MongoDB의 create는 insert를 통해서 이루어지는데, 만약 collection이 존재하지 않는다면, 'insert' 명령어는 collection을 새로 생성한다.

 

따라서 MongoDB는 docments를 collection에 넣기 위한 insert 메소드를 다음과 같이 제공한다.

  • db.collection.insertOne()
  • db.collection.insertMany()

먼저 db.collection.insertOne()은 하나의 document를 collection에 넣는 명령어이다.

return은 

db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

- insert가 성공하면 document의 _id를 리턴해준다.

 

 

db.collection.insertMany()는 여러개의 documents를 insert하기 위한 명령어 이며, 다음과 같이 사용한다.

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

- insertMany()는 데이터를 넣기위해 Array형태로 입력을 하며, 리턴되는 _id 또한 array 형태로 반환된다.

 

 

Read Operation(Find)

Read는 collection에 있는 document를 읽기위해 사용하는 동작이며, Find라는 함수를 통해 동작을 수행한다. 

  • db.collection.find()

find()는 쿼리 필터를 이용하여 documnet를 읽어올 수 있는데 예시를 통해 살펴보자

 

1. 데이터를 먼저 입력해준다.

db.inventory.insertMany( [
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);

 

2. 전제 documnet를 조회하거나, 조건을 입력하여 데이터를 조회한다.

db.inventory.find({}) // 전체 document 조회
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )

find()함수를 실행하게 되면, 다음과 같이 iddocument를 함께 리턴해준다.

(만약 조건에 해당하는 document가 없다면 아무것도 리턴하지 않는다.)

 

 

쿼리 필터 즉, 조건을 넣어 document를 찾을 때, 필드와 내부 필드를 함께 붙여 사용할 수도 있다.

db.inventory.find( { "size.uom": "in" } )

또한 조건에 operator를 사용하여 데이터를 검색할 수 있다.

{ <field1>: { <operator1>: <value1> }, ... }
db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

위는 size 필드의 h 는 15이상이며, uom은 "in"이며, status는 "D"인 document를 찾는다.

 

필요 데이터만 조회하기

위의 find는 일반적으로 _id를 포함한 document의 모든 데이터를 가져온다. 하지만 RDBMS의 Select size.h from inventory where ~와 같이 특정 필드만 가져오기 위해서는 다음과 같이 사용한다.

db.collection.find({조건}, {가져올 필드 : 1})
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } }, {item : 1 } )

위에서 만약 _id 없이 item 필드만 조회하고 싶다면 다음과 같이 사용한다.

db.collection.find({조건}, { _id : 0, 가져올 필드 : 1})
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } }, { _id : 0, item : 1 } )

 

만약 특정 필드를 제외한 모든 필드를 조회하기 위해서는 다음과 같이 사용한다.

db.collection.find({조건}, { _id : 0, 제외할 필드 : 0})
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } }, { _id : 0, item : 0 } )

 

배열 조건 조회

특정 필드 값이 배열로 되어 있고, 그 데이터를 필드를 이용해 조회하려고 한다.

그렇게 된다면 db.collection.find( { <field> : [<value1>, <value2>]  } ) 와 같이 입력을 하는데, 이때는 정확한 순서가 일치하는 documnet만 불러오게 된다.

따라서, 순서에 상관없이 조건을 입력하기 위해서는 다음과 같이 사용한다.

db.collection.find( { <field> : { &all : [<value1>, <value2>] } } )

 

비교 연산자

조건 조회를 할때, 일치하는 값을 불러오는 것이 아닌 비교 연산자를 통해서 documnet를 조회할 수 있다.

비교 연산자는 다음과 같다.

 

출처 : https://docs.mongodb.com/manual/reference/operator/query-comparison/

 

논리 연산자

비교 연산자 뿐만 아니라, 논리 연산자를 통해서도 데이터를 조회할 수 있는데 사용할 수 있는 논리 연산자는 다음과 같다.

 

출처 : https://docs.mongodb.com/manual/reference/operator/query-logical/

Null 값과 필드 존재여부 조회

조건에 null 값을 입력하면, 필드가 null 인 값도 조회하지만, 필드가 존재하지 않는 documnet도 조회한다.

db.inventory.insertMany([
   { _id: 1, item: null },
   { _id: 2 }
])

db.inventory.find( { item: null } )

 

필드가 존재 하지 않는 documnet를 조회하기 위해서는 다음과 같은 식을 사용한다.

db.inventory.find( { item : { $exists: false } } )

또한, 필드의 밸류가 null인 값을 조회하기 위해 type 연산자를 사용할 수 있다. ( type number는 하단 링크 참고하시면 됩니다. / 10 : null)

https://docs.mongodb.com/manual/reference/bson-types/

db.inventory.find( { item : { $type: 10 } } )

Cursor

MongoDB에서 find 함수를 사용하면 객체 타입은 Cursor 형태의 객체로 반환이 된다.

기본적으로 MongoDB는 커서 반복을 최대 20회로 조회한다.

예를들어, 다음과 같이 조회시에 documnet를 cursor에 저장하여 하나씩 반복하여 출력하는데 커서를 변수로 지정하여 사용하지 않을 경우에는 최대 20개의 documnet만 조회된다.

db.inventory.find( { status : "A" } )

 

Mongo shell에서 cursor를 사용하는 방법은 다음과 같다.

var myCursor = db.inventory.find( { status : "A" } );

 

기본적으로 커서를 이용하여 데이터를 반복 출력하는 방법은 위의 식처럼 변수를 호출하는 방법과 아래의 next()함수를 사용하는 방법이 있다.

var myCursor = db.inventory.find( { status : "A" } );

while (myCursor.hasNext()) {
   print(tojson(myCursor.next()));
}

또한, 아래의 식은 위의 식과 같은 값을 출력해준다.

var myCursor = db.inventory.find( { status : "A" } );

while (myCursor.hasNext()) {
   printjson(myCursor.next());
}
var myCursor = db.inventory.find( { status : "A" } );

myCursor.forEach(printjson);

아래와 같이 커서 객체를 Array 형태로도 변환할 수 있다.

var myCursor = db.inventory.find( { status : "A" } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];

Java에서 Cursor를 사용하는 방법은 다음과 같다.

MongoCollection<Document> collection = sMongoDatabase.getCollection(collectionName);
FindIterable<Document> findIterable = collection.find(query.getQuery());
MongoCursor<Document> cursor = findIterable.iterator();
try {
    if (cursor.hasNext()) {
        return cursor.next();
    }
} finally {
    cursor.close();
}

Update Operation(Update, Replace)

Update는 collection의 documents를 수정하기 위한 동작이다.

  • db.collection.updateOne()
  • db.collection.updateMany()
  • db.collection.replaceOne()

updateOne()은 하나의 document를 수정한다. update 시에는 조건을 넣어 수정할 document를 지정하는데 여러 document가 조회될 경우 가장 처음 document를 수정한다.

db.inventory.updateOne(
   { item: "paper" },    //조건
   {
     $set: { "size.uom": "cm", status: "P" },
     $currentDate: { lastModified: true }
   }
)

 

여러 데이터를 한번에 수정하기 위해서는 updateMany()를 사용한다. 사용방법은 동일하다.

db.inventory.updateMany(
   { "qty": { $lt: 50 } },
   {
     $set: { "size.uom": "in", status: "P" },
     $currentDate: { lastModified: true }
   }
)

위의 update~() 두가지 메소드에서 $set을 통해 필드 값을 수정했다. replaceOne()은 위의 update들과는 다르게 들어온 인자값으로 documnet를 대체한다.

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

 

Delete Operation(Delete)

Delete는 colletion의 documents를 삭제하는 동작이다.

  • db.collection.deleteOne()
  • db.collection.deleteMany()

먼저 deleteMany()는 여러개의 documnets를 삭제하는데 다음과 같이 전체 document를 삭제할 수 있다.

db.inventory.deleteMany({})

또한 조건을 넣어 해당하는 document를 삭제할 수 있다.

db.inventory.deleteMany({ <field> : <value> })

deleteOne()은 위와 동일하나, 조회된 documents 중 가장 첫번째 document를 삭제한다.

db.inventory.deleteOne({ <field> : <value> })

 

Comments