MongoDB

혀니·2024년 7월 26일
0

MongoDB

-> sql이 아니다 보니 함수형으로 호출하는 방식이 사용됨

출처: Beginersbook.com


문서 : https://www.w3schools.com/mongodb/


cmd를 열고 mongosh를 친다.

데이터베이스 조회

show dbs

데이터베이스 삭제

db.dropDatabase()

데이터베이스 선택 (없으면 생성됨)

use db명

create

컬렉션 생성

  • db.createCollection("book")
  • db.book.insertOne(object) : 있으면 insert, 없어도 에러나지 않고 추가로 만들어짐

insert

한 건일 경우

db.posts.insertOne({
  title: "Post Title 1",
  body: "Body of post.",
  category: "News",
  likes: 1,
  tags: ["news", "events"],
  date: Date()
})

여러 건일 경우

db.posts.insertMany([  
  {
    title: "Post Title 2",
    body: "Body of post.",
    category: "Event",
    likes: 2,
    tags: ["news", "events"],
    date: Date()
  },
  {
    title: "Post Title 3",
    body: "Body of post.",
    category: "Technology",
    likes: 3,
    tags: ["news", "events"],
    date: Date()
  },
  {
    title: "Post Title 4",
    body: "Body of post.",
    category: "Event",
    likes: 4,
    tags: ["news", "events"],
    date: Date()
  }
])

DELETE

컬렉션을 삭제

db.book.drop()

데이터베이스 삭제

db.dropDatabase()

테이블 내용 삭제

db.book.deleteOne( {bookid: 11} )

테이블 내용 모두 삭제

db.book.deleteMany( {} )
db.book.deleteMany()는 오류남

조회

데이터베이스 내용 조회

db.book.find()

특정 조건 찾기

db.book.find({bookid: 10} )

프로젝션: 보고자 하는 필드 선택

bookid와 bookname 필드만 보여줌

db.book.find({}, {bookid: 1, bookname: 1})

bookid와 bookname을 제외한 필드만 보여줌

db.book.find({}, {bookid: 0, bookname: 0})

db.book.find({}, {bookid: 1, bookname: 0})은 안되지만, _id: 0은 설정 가능함 (기본적으로 그냥 붙는 ObjectId)

db.book.find( {bookname: '올림픽 이야기'}, {_id:0, bookid:1, bookname:1})

UPDATE

1. 조건에 맞는 하나 업데이트

db.book.updateOne( { bookname: '올림픽 이야기'}, { $set: {price: 7000} })
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

11번 아이디가 없을 때 업데이트 - 매치되는 값 찾지 못함

db.book.updateOne( {bookid:11}, {$set: {price: 6000, saleprice:5000} })
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 0,
  modifiedCount: 0,
  upsertedCount: 0
}

UPSERT

upsert : true로 하면 조건에 맞는게 없어도 그냥 새로 만들어줌.

db.book.updateOne( {bookid:11}, {$set: {price: 6000, saleprice:5000}}, { upsert:true })

결과

{
  acknowledged: true,
  insertedId: ObjectId('66a1d225c0438061aade2c43'),
  matchedCount: 0,
  modifiedCount: 0,
  upsertedCount: 1
}

조회

{
    _id: ObjectId('66a1d225c0438061aade2c43'),
    bookid: 11,
    price: 6000,
    saleprice: 5000
  }

2. 여러개 업데이트 - 모든 행 price 10씩 증가됨(inc)

db.book.updateMany({}, {$inc: {price:10} })

쿼리 연산자

비교

$eq : 값과 같은 거 찾기(동등)

db.book.find( {bookid: { $eq: 5 } })

$ne : 값이 같지 않은 거(not)

$gt : 값보다 큰 것들 찾기(초과)

db.book.find( {bookid: { $gt: 5 } })

$gte : 값도 포함해야 될때. (이상)

db.book.find( {price: {$gte: 20000} })

$lt : 미만
$lte : 이하

$in : 배열 내에서 값이 일치하는 것 찾기

조건 두개 넣을 때 (15000원 이상, 20000원 이하)

db.book.find( {price: {$gte: 15000, $lte: 20000} }

논리적

$and : 여러 조건을 줄 때 쿼리가 모두 일치(and)
$or : 두 쿼리 중 일치하는게 있으면 반환(or)
$nor : 두 쿼리가 모두 일치하지 않으면 반환(nor)
$not : 쿼리와 일치하지 않으면 반환(not)

bookid가 6보다 작고, price가 20000보다 크거나 같은 거 찾기

db.book.find(
... {
...     $and: [
...           { bookid: {$lt:6} },
...           { price: {$gte: 20000} }
...     ]
... })

평가

$regex : 필드 값을 평가할 때 정규 표현식을 사용할 수 있음

  • 정규 표현식은 부분 문자열 일치를 기본으로 해서 명시적 와일드 카드 안써도 됨
  • $options : 정규 표현식 옵션 설정

    i : 대소문자 구분하지 않고 검색
    m : 여러 줄에 걸쳐 검색. 텍스트의 각 줄을 개별 문자열로 취급
    s : .문자가 개행 문자(\n)을 포함한 모든 문자와 일치하는지 확인(여러줄에서 쓰임)
    x : 패턴 내 공백과 주석을 무시

$text : 텍스트 검색 수행
$ where : 자바스크립트 표현식을 사용하여 값 일치시킴


update 연산자

$unset : 컬럼을 삭제

bookid가 5보다 큰 데이터 price 컬럼 삭제

db.book.updateMany(
... {
...     bookid: {$gt: 5}
... },
... {
...     $unset: {price: ''}
... })

함수 형태의 sort(), limit(), skip()

sort()

sort({ 필드: 1 } ) : 1이면 오름차순, -1이면 내림차순

db.book.find().sort( {price: 1})

limit(n): n개만 가져오기

5개만 가져오기

db.book.find().limit(5)

skip(n) : 데이터 스킵

offset은 없고 대신 skip(n)은 있음
skip(3).limit(5)면
아이디 1,2,3은 스킵하고 4부터 5개 데이터 가져옴


집계 파이프 라인(Aggregation)

Aggregation

: $group, $sort, $limit, $match 등등등 각 스테이지(단계)를 나열해야 할 때(파이프라인)

  • 빅데이터에서 데이터를 걸러낼 때 사용

price의 합 조회

SQL

  select sum(price) totalPrice from book;

MongoDB

db.book.aggregate(
... [
...     { $group: { _id: null, totalPrice: { $sum: "$price" } } }
... ])

결과

	[ { _id: null, totalPrice: 144500 } ]

출판사 별 총 가격

SQL

	select publisher, sum(price) totalPrice from group by publisher;

MongoDB

db.book.aggregate( [ { $group: { _id: "$publisher", totalPrice: { $sum: "$price" } } }] )
[
  { _id: '굿스포츠', totalPrice: 21000 },
  { _id: '삼성당', totalPrice: 7500 },
  { _id: '나무수', totalPrice: 13000 },
  { _id: 'Pearson', totalPrice: 13000 },
  { _id: '대한미디어', totalPrice: 57000 },
  { _id: '이상미디어', totalPrice: 33000 }

출판사 별 총 가격을 오름차순으로 정렬

SQL

select publisher, sum(price) totalPrice from group by publisher order by totalPrice;

Mongo

db.book.aggregate( [ { $group: { _id: "$publisher", totalPrice: { $sum: "$price" } } }, { $sort: {totalPrice: 1}}] )

bookid가 2보다 큰 것 중에 출판사 별 총 가격을 오름차순으로 정렬

# MongoDB
db.book.aggregate( [ { $match: { bookid: { $gt: 2 } } }, {$group: {_id: "$publisher", totalPrice: {$sum: "$price"}}}, {$sort: {totalPrice:1}}])
# 결과
[
  { _id: '삼성당', totalPrice: 7500 },
  { _id: 'Pearson', totalPrice: 13000 },
  { _id: '굿스포츠', totalPrice: 14000 },
  { _id: '이상미디어', totalPrice: 33000 },
  { _id: '대한미디어', totalPrice: 57000 }
]

자바 MongDB 연결

package com.mycom.myapp.dao;

import java.awt.print.Book;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mycom.myapp.dto.BookDto;
import org.bson.Document;
import org.bson.conversions.Bson;

import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Updates.combine;
import static com.mongodb.client.model.Updates.set;

// jdbc처럼 연결해줘야 함
public class BookDao {

    static final String CONNECTION_STRING = "mongodb://localhost:27017"; // db는 따로 씀
    static final String DATABASE_NAME = "madangdb"; // db 이름
    static final String COLLECTION_NAME = "book"; // 테이블 이름

    // username, password 필요 x

    private MongoClient mongoClient; // jdbc Connection 유사
    private MongoDatabase database;
    private MongoCollection<Document> collection; // import org.bson.Document

    // 생성자 mongodb 연결 초기화
    public BookDao() {
        try{
            this.mongoClient = MongoClients.create(CONNECTION_STRING); // Client's'임. s 있음
            this.database = this.mongoClient.getDatabase(DATABASE_NAME);
            this.collection = database.getCollection(COLLECTION_NAME);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public List<BookDto> listBook(){
        List<BookDto> bookList = new ArrayList<>();

        // collection.find() : 반환 값 형변환 해야 함. iterable하므로 for each 가능
        for(Document doc : collection.find()){
            BookDto bookDto = new BookDto();
            bookDto.setBookId(doc.getInteger("bookid")); // document에서 bookid 필드를 가져옴
            bookDto.setBookName(doc.getString("bookname"));
            bookDto.setPublisher(doc.getString("publisher"));
            bookDto.setPrice(doc.getInteger("price"));

            bookList.add(bookDto);
        }

        return bookList;
    }

    public List<BookDto> listBookSearch(String searchWord){
        List<BookDto> bookList = new ArrayList<>();

        Document filterDocument = new Document("$regex", searchWord).append("$options", "i");
        Document bookNameFilter = new Document("bookname", filterDocument);

        for(Document doc : collection.find(bookNameFilter)){
            BookDto bookDto = new BookDto();
            bookDto.setBookId(doc.getInteger("bookid")); // document에서 bookid 필드를 가져옴
            bookDto.setBookName(doc.getString("bookname"));
            bookDto.setPublisher(doc.getString("publisher"));
            bookDto.setPrice(doc.getInteger("price"));

            bookList.add(bookDto);
        }

        return bookList;
    }

    public BookDto detailBook(int bookid) {
        Document doc = collection.find( eq("bookid", bookid )).first();
        BookDto bookDto = null;

        if( doc != null ){
            bookDto = new BookDto();
            bookDto.setBookId(doc.getInteger("bookid")); // document에서 bookid 필드를 가져옴
            bookDto.setBookName(doc.getString("bookname"));
            bookDto.setPublisher(doc.getString("publisher"));
            bookDto.setPrice(doc.getInteger("price"));

        }
        return bookDto;
    }

    public void insertBook(BookDto bookDto) {
        Document document = new Document("bookid", bookDto.getBookId())
                .append("bookname", bookDto.getBookName())
                .append("publisher", bookDto.getPublisher())
                .append("price", bookDto.getPrice());
        collection.insertOne(document);
    }

    public void updateBook(BookDto bookDto) {
        Bson filter = eq("bookid", bookDto.getBookId());
        Bson update = combine(
                set("bookname", bookDto.getBookName()),
                set("publisher", bookDto.getPublisher()),
                set("price", bookDto.getPrice())
        );
        collection.updateOne(filter, update);
    }

    public void deleteBook(int bookid) {
        collection.deleteOne(eq("bookid", bookid));
    }
}

0개의 댓글