본문 바로가기

K8S

Percona Distribution for MongoDB 오퍼레이터 - 기본설치 (1/3)

Gasida님의 Database Operator In Kubernetes study(=DOIK) 스터디 진행 중 테스트 한 내용입니다.

Percona Distribution for MongoDB 오퍼레이터 - 기본설치 (1/3)
1. Percona Operator for MongoDB 설치
2. K8S 헤드리스서비스 접속정보 확인
3. MongoDB 접속 확인
4. MongoDB 기본CRUD테스트


Percona Operator for MongoDB

https://www.percona.com/doc/kubernetes-operator-for-psmongodb/architecture.html

  • 오퍼레이터는 PSMDB Replica set 으로 디자인되어 있습니다.
  • 클라이언트 애플리케이션은 mongo+srv URI 주소로 접속합니다.
  • 오퍼레이터는 PerconaServerMongoDB 오브젝트를 사용 하여, 각 Percona Server for MongoDB 를 관리하며 적한 Replica Set 을 제공합니다.
  • 노드에 장애가 발생하면, mongod 프로세스가 있는 포드가 다른 노드에 자동으로 다시 생성됩니다. 
  • 장애발생 노드가 primary  서버일 경우replica set은 새로운 primary 서버를 선택합니다.
  • 실패한 노드가 Operator를 실행 중인 경우, Kubernetes는 다른 노드에서 Operator를 다시 시작하므로 작동이 중단되지 않습니다.


1. Percona Operator for MongoDB 설치

CRD설치

# CRD 설치
$ kubectl apply --server-side -f ~/DOIK/4/crd.yaml
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbs.psmdb.percona.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbbackups.psmdb.percona.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbrestores.psmdb.percona.com serverside-applied

# CRD 확인
$ kubectl get crd
NAME                                             CREATED AT
perconaservermongodbbackups.psmdb.percona.com    2022-06-19T02:34:14Z
perconaservermongodbrestores.psmdb.percona.com   2022-06-19T02:34:14Z
perconaservermongodbs.psmdb.percona.com          2022-06-19T02:34:14Z

 

▶ 테스트 편의를 위한 NameSpace 변경 및 DB닉네임 변수설정

$ kubectl create ns psmdb
namespace/psmdb created

$ kubens psmdb
kubens psmdb
Context "DOIK-Lab" modified.
Active namespace is "psmdb".

$ MYNICK=miny

 

▶ RBAC 설치

$ kubectl apply -f ~/DOIK/4/rbac.yaml

 

 오퍼레이터 설치

$ kubectl apply -f ~/DOIK/4/pomdb.yaml

 

계정 정보를 위한 base64 decode secret파일 생성 

$ cat ~/DOIK/4/secrets.yaml
 apiVersion: v1
 kind: Secret
 metadata:
   name: ${MYCLUSTERNAME}-secrets
 type: Opaque
 stringData:
   MONGODB_BACKUP_USER: backup
   MONGODB_BACKUP_PASSWORD: backup123456
   MONGODB_CLUSTER_ADMIN_USER: clusterAdmin
   MONGODB_CLUSTER_ADMIN_PASSWORD: clusterAdmin123456
   MONGODB_CLUSTER_MONITOR_USER: clusterMonitor
   MONGODB_CLUSTER_MONITOR_PASSWORD: clusterMonitor123456
   MONGODB_USER_ADMIN_USER: userAdmin
   MONGODB_USER_ADMIN_PASSWORD: userAdmin123456
   PMM_SERVER_USER: admin
   PMM_SERVER_PASSWORD: admin
   
$ MYCLUSTERNAME=$MYNICK envsubst < ~/DOIK/4/secrets.yaml | kubectl apply -f -
secret/miny-secrets created


NAME           TYPE     DATA   AGE
miny-secrets   Opaque   10     68s

# 아래와 같이 난수로 표시 됨.
$ kubectl get secret $MYNICK-secrets -o json | jq
{
  "apiVersion": "v1",
  "data": {
    "MONGODB_BACKUP_PASSWORD": "YmFja3VwMTIzNDU2",
    "MONGODB_BACKUP_USER": "YmFja3Vw",
    "MONGODB_CLUSTER_ADMIN_PASSWORD": "Y2x1c3RlckFkbWluMTIzNDU2",
    "MONGODB_CLUSTER_ADMIN_USER": "Y2x1c3RlckFkbWlu",
    "MONGODB_CLUSTER_MONITOR_PASSWORD": "Y2x1c3Rlck1vbml0b3IxMjM0NTY=",
    "MONGODB_CLUSTER_MONITOR_USER": "Y2x1c3Rlck1vbml0b3I=",
    "MONGODB_USER_ADMIN_PASSWORD": "dXNlckFkbWluMTIzNDU2",
    "MONGODB_USER_ADMIN_USER": "dXNlckFkbWlu",
    "PMM_SERVER_PASSWORD": "YWRtaW4=",
    "PMM_SERVER_USER": "YWRtaW4="
  },
  "kind": "Secret",
  "metadata": {
    "annotations": {
      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{\"annotations\":{},\"name\":\"miny-secrets\",\"namespace\":\"psmdb\"},\"stringData\":{\"MONGODB_BACKUP_PASSWORD\":\"backup123456\",\"MONGODB_BACKUP_USER\":\"backup\",\"MONGODB_CLUSTER_ADMIN_PASSWORD\":\"clusterAdmin123456\",\"MONGODB_CLUSTER_ADMIN_USER\":\"clusterAdmin\",\"MONGODB_CLUSTER_MONITOR_PASSWORD\":\"clusterMonitor123456\",\"MONGODB_CLUSTER_MONITOR_USER\":\"clusterMonitor\",\"MONGODB_USER_ADMIN_PASSWORD\":\"userAdmin123456\",\"MONGODB_USER_ADMIN_USER\":\"userAdmin\",\"PMM_SERVER_PASSWORD\":\"admin\",\"PMM_SERVER_USER\":\"admin\"},\"type\":\"Opaque\"}\n"
    },
    "creationTimestamp": "2022-06-19T02:49:35Z",
    "name": "miny-secrets",
    "namespace": "psmdb",
    "resourceVersion": "3622",
    "uid": "74668fe8-bb24-48de-a678-746a9a07b550"
  },
  "type": "Opaque"
}

 

클러스터 생성 : 복제 세트(3개 파드)

$ MYCLUSTERNAME=$MYNICK envsubst < ~/DOIK/4/mycluster1.yaml | kubectl apply -f -
perconaservermongodb.psmdb.percona.com/miny-db created

 

클러스터 파드 정보 확인

$ kubectl get pod -owide
NAME                                               READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
miny-db-rs0-0                                      1/1     Running   0          2m48s   172.16.1.3   k8s-w1   <none>           <none>
miny-db-rs0-1                                      1/1     Running   0          116s    172.16.2.3   k8s-w2   <none>           <none>
miny-db-rs0-2                                      1/1     Running   0          65s     172.16.3.5   k8s-w3   <none>           <none>
percona-server-mongodb-operator-54d7456f5b-zpvcs   1/1     Running   0          3m4s    172.16.0.4   k8s-m    <none>           <none>

$ kubectl get sts -owide
NAME          READY   AGE     CONTAINERS   IMAGES
miny-db-rs0   3/3     4m36s   mongod       percona/percona-server-mongodb:5.0.7-6

$ kubectl get svc
NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
miny-db-rs0   ClusterIP   None         <none>        27017/TCP   5m9s

$ kubectl get endpoints,endpointslice
NAME                    ENDPOINTS                                            AGE
endpoints/miny-db-rs0   172.16.1.3:27017,172.16.2.3:27017,172.16.3.5:27017   5m22s

NAME                                               ADDRESSTYPE   PORTS   ENDPOINTS                          AGE
endpointslice.discovery.k8s.io/miny-db-rs0-lfxhg   IPv4          27017   172.16.1.3,172.16.2.3,172.16.3.5   5m22s

 

2. 헤드리스 서비스 접속정보 확인

헤드리스 서비스 확인

$ kubectl get svc,ep
NAME                  TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
service/miny-db-rs0   ClusterIP   None         <none>        27017/TCP   9m53s

NAME                    ENDPOINTS                                            AGE
endpoints/miny-db-rs0   172.16.1.3:27017,172.16.2.3:27017,172.16.3.5:27017   9m53s

 

엔드포인트 슬라이스 정보 확인

$ kubectl describe endpointslices
Name:         miny-db-rs0-lfxhg
Namespace:    psmdb
Labels:       app.kubernetes.io/instance=miny-db
              app.kubernetes.io/managed-by=percona-server-mongodb-operator
              app.kubernetes.io/name=percona-server-mongodb
              app.kubernetes.io/part-of=percona-server-mongodb
              app.kubernetes.io/replset=rs0
              endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.io
              kubernetes.io/service-name=miny-db-rs0
              service.kubernetes.io/headless=
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: 2022-06-19T03:07:54Z
AddressType:  IPv4
Ports:
  Name     Port   Protocol
  ----     ----   --------
  mongodb  27017  TCP
Endpoints:
  - Addresses:  172.16.1.3
    Conditions:
      Ready:    true
    Hostname:   miny-db-rs0-0
    TargetRef:  Pod/miny-db-rs0-0
    NodeName:   k8s-w1
    Zone:       <unset>
  - Addresses:  172.16.2.3
    Conditions:
      Ready:    true
    Hostname:   miny-db-rs0-1
    TargetRef:  Pod/miny-db-rs0-1
    NodeName:   k8s-w2
    Zone:       <unset>
  - Addresses:  172.16.3.5
    Conditions:
      Ready:    true
    Hostname:   miny-db-rs0-2
    TargetRef:  Pod/miny-db-rs0-2
    NodeName:   k8s-w3
    Zone:       <unset>
Events:         <none>

 

nslookup정보 확인

$ kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh
If you don't see a command prompt, try pressing enter.
                    dP            dP                           dP   
                    88            88                           88   
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P 
88'  `88 88ooood8   88   Y8ooooo. 88'  `88 88'  `88 88'  `88   88   
88    88 88.  ...   88         88 88    88 88.  .88 88.  .88   88   
dP    dP `88888P'   dP   `88888P' dP    dP `88888P' `88888P'   dP   
                                                                    
Welcome to Netshoot! (github.com/nicolaka/netshoot)

$ nslookup miny-db-rs0
Server:         10.200.1.10
Address:        10.200.1.10#53

Name:   miny-db-rs0.psmdb.svc.cluster.local
Address: 172.16.3.5
Name:   miny-db-rs0.psmdb.svc.cluster.local
Address: 172.16.2.3
Name:   miny-db-rs0.psmdb.svc.cluster.local
Address: 172.16.1.3

$ nslookup -type=srv miny-db-rs0
Server:         10.200.1.10
Address:        10.200.1.10#53

miny-db-rs0.psmdb.svc.cluster.local     service = 0 33 27017 miny-db-rs0-0.miny-db-rs0.psmdb.svc.cluster.local.
miny-db-rs0.psmdb.svc.cluster.local     service = 0 33 27017 miny-db-rs0-1.miny-db-rs0.psmdb.svc.cluster.local.
miny-db-rs0.psmdb.svc.cluster.local     service = 0 33 27017 miny-db-rs0-2.miny-db-rs0.psmdb.svc.cluster.local.


$ nslookup miny-db-rs0-0.miny-db-rs0                                                 
Server:         10.200.1.10
Address:        10.200.1.10#53

Name:   miny-db-rs0-0.miny-db-rs0.psmdb.svc.cluster.local
Address: 172.16.1.3

$ nslookup miny-db-rs0-1.miny-db-rs0
Server:         10.200.1.10
Address:        10.200.1.10#53

Name:   miny-db-rs0-1.miny-db-rs0.psmdb.svc.cluster.local
Address: 172.16.2.3


$ nslookup miny-db-rs0-2.miny-db-rs0
Server:         10.200.1.10
Address:        10.200.1.10#53

Name:   miny-db-rs0-2.miny-db-rs0.psmdb.svc.cluster.local
Address: 172.16.3.5

 

3. MongoDB 클러스터 접속 확인

 테스트 편의를 위한 DB이름 변수 설정

MYNICK=miny
IMGVER=$(kubectl get perconaservermongodbs $MYNICK-db -o jsonpath={.spec.image} | cut -d ':' -f 2)

 

 테스트용 클라이언트파드 배포

$cat ~/DOIK/4/myclient.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: ${PODNAME}
   labels:
     app: myclient
 spec:
   nodeName: k8s-m
   containers:
   - name: ${PODNAME}
     image: percona/percona-server-mongodb:${VERSION}
     command: ["tail"]
     args: ["-f", "/dev/null"]
   terminationGracePeriodSeconds: 0

$ for ((i=1; i<=3; i++)); do PODNAME=myclient$i VERSION=$IMGVER envsubst < ~/DOIK/4/myclient.yaml | kubectl apply -f - ; done
pod/myclient1 created
pod/myclient2 created
pod/myclient3 created

 

[터미널1] 클러스터 접속(ADMIN_USER)

$ kubectl exec -it myclient1 -- mongo --quiet "mongodb+srv://userAdmin:userAdmin123456@$MYNICK-db-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"
Welcome to the Percona Server for MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        https://www.percona.com/doc/percona-server-for-mongodb
Questions? Try the support group
        https://www.percona.com/forums/questions-discussions/percona-server-for-mongodb

rs0:PRIMARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
rs0:PRIMARY> 
rs0:PRIMARY> 
rs0:PRIMARY> db
admin
rs0:PRIMARY>

 

 [터미널1]  데이터베이스를 사용할 유저 생성

rs0:PRIMARY> db.createUser({user: "miny" , pwd: "qwe123" , roles: [ "userAdminAnyDatabase", "dbAdminAnyDatabase","readWriteAnyDatabase"]})
Successfully added user: {
        "user" : "miny",
        "roles" : [
                "userAdminAnyDatabase",
                "dbAdminAnyDatabase",
                "readWriteAnyDatabase"
        ]
}
rs0:PRIMARY>

 

[터미널2] 클러스터 접속(CLUSTER_USER)

$ kubectl exec -it myclient2 -- mongo --quiet "mongodb+srv://clusterAdmin:clusterAdmin123456@miny-db-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"

 

 [터미널2] 클러스터 정보 확인

rs0:PRIMARY> rs.status()['members']
[
        {
                "_id" : 0,
                "name" : "miny-db-rs0-0.miny-db-rs0.psmdb.svc.cluster.local:27017",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 3193,
                "optime" : {
                        "ts" : Timestamp(1655611147, 1),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2022-06-19T03:59:07Z"),
                "lastAppliedWallTime" : ISODate("2022-06-19T03:59:07.950Z"),
                "lastDurableWallTime" : ISODate("2022-06-19T03:59:07.950Z"),
                "syncSourceHost" : "",
                "syncSourceId" : -1,
                "infoMessage" : "",
                "electionTime" : Timestamp(1655608038, 2),
                "electionDate" : ISODate("2022-06-19T03:07:18Z"),
                "configVersion" : 93252,
                "configTerm" : -1,
                "self" : true,
                "lastHeartbeatMessage" : ""
        },
        {
                "_id" : 1,
                "name" : "miny-db-rs0-1.miny-db-rs0.psmdb.svc.cluster.local:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 3111,
                "optime" : {
                        "ts" : Timestamp(1655611147, 1),
                        "t" : NumberLong(1)
                },
                "optimeDurable" : {
                        "ts" : Timestamp(1655611147, 1),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2022-06-19T03:59:07Z"),
                "optimeDurableDate" : ISODate("2022-06-19T03:59:07Z"),
                "lastAppliedWallTime" : ISODate("2022-06-19T03:59:07.950Z"),
                "lastDurableWallTime" : ISODate("2022-06-19T03:59:07.950Z"),
                "lastHeartbeat" : ISODate("2022-06-19T03:59:14.935Z"),
                "lastHeartbeatRecv" : ISODate("2022-06-19T03:59:15.643Z"),
                "pingMs" : NumberLong(0),
                "lastHeartbeatMessage" : "",
                "syncSourceHost" : "miny-db-rs0-0.miny-db-rs0.psmdb.svc.cluster.local:27017",
                "syncSourceId" : 0,
                "infoMessage" : "",
                "configVersion" : 93252,
                "configTerm" : -1
        },
        {
                "_id" : 2,
                "name" : "miny-db-rs0-2.miny-db-rs0.psmdb.svc.cluster.local:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 3067,
                "optime" : {
                        "ts" : Timestamp(1655611147, 1),
                        "t" : NumberLong(1)
                },
                "optimeDurable" : {
                        "ts" : Timestamp(1655611147, 1),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2022-06-19T03:59:07Z"),
                "optimeDurableDate" : ISODate("2022-06-19T03:59:07Z"),
                "lastAppliedWallTime" : ISODate("2022-06-19T03:59:07.950Z"),
                "lastDurableWallTime" : ISODate("2022-06-19T03:59:07.950Z"),
                "lastHeartbeat" : ISODate("2022-06-19T03:59:15.827Z"),
                "lastHeartbeatRecv" : ISODate("2022-06-19T03:59:16.526Z"),
                "pingMs" : NumberLong(1),
                "lastHeartbeatMessage" : "",
                "syncSourceHost" : "miny-db-rs0-1.miny-db-rs0.psmdb.svc.cluster.local:27017",
                "syncSourceId" : 1,
                "infoMessage" : "",
                "configVersion" : 93252,
                "configTerm" : -1
        }
]
rs0:PRIMARY>

 

4. 기본 CRUD 테스트 

INSERT

  → miny 데이터베이스 접속(없으면 자동생성)

rs0:PRIMARY> use miny;
switched to db miny

 

  → users 콜렉션 생성

rs0:PRIMARY> db.createCollection("users")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1655611859, 2),
                "signature" : {
                        "hash" : BinData(0,"5o3DhCmRozTk0BJHXLLnKiLXbXo="),
                        "keyId" : NumberLong("7110782378204725253")
                }
        },
        "operationTime" : Timestamp(1655611859, 2)
}

 

  → users 콜렉션에 도큐먼트 넣기 : One Insert

rs0:PRIMARY> db.users.insertOne(
...  {
...   name: "gasida",
...   age: 30,
...   status: "pending",
...  }
... )
{
        "acknowledged" : true,
        "insertedId" : ObjectId("62aea1e1254abf95397dcbc4")
}

 

  → users 콜렉션에서 도큐먼트 확인

rs0:PRIMARY> db.users.find()
{ "_id" : ObjectId("62aea1e1254abf95397dcbc4"), "name" : "gasida", "age" : 30, "status" : "pending" }

 

  →  users 콜렉션에 도큐먼트 넣기 : Insert Many

rs0:PRIMARY> db.users.insertMany(
...  [
...   { subject: "abc1", author: "xyz1", views: 10 },
...   { subject: "abc2", author: "xyz2", views: 20 },
...   { subject: "abc3", author: "xyz3", views: 30 }
...  ]
... )
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("62aea208254abf95397dcbc5"),
                ObjectId("62aea208254abf95397dcbc6"),
                ObjectId("62aea208254abf95397dcbc7")
        ]
}

 

  →  users  콜렉션 조회

rs0:PRIMARY> db.users.find()
{ "_id" : ObjectId("62aea1e1254abf95397dcbc4"), "name" : "gasida", "age" : 30, "status" : "pending" }
{ "_id" : ObjectId("62aea208254abf95397dcbc5"), "subject" : "abc1", "author" : "xyz1", "views" : 10 }
{ "_id" : ObjectId("62aea208254abf95397dcbc6"), "subject" : "abc2", "author" : "xyz2", "views" : 20 }
{ "_id" : ObjectId("62aea208254abf95397dcbc7"), "subject" : "abc3", "author" : "xyz3", "views" : 30 }

 

SELECT : 다양한 조회조건 검색, Ansi SQL과 문법비교

  →  테스트용 employees 콜렉션 생성 

rs0:PRIMARY> db.createCollection("employees")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1655612152, 1),
                "signature" : {
                        "hash" : BinData(0,"JeXRpUw6LWy7LcbnrUyaeKo+iek="),
                        "keyId" : NumberLong("7110782378204725253")
                }
        },
        "operationTime" : Timestamp(1655612152, 1)
}

 

  →  테스트용 employees 콜렉션에 테스트 데이터 iNSERT

rs0:PRIMARY> db.employees.insertMany(
... [
...   { user_id: "user01", age: 45, status: "A" },
...   { user_id: "user02", age: 35, status: "A" },
...   { user_id: "user03", age: 25, status: "B" },
...   { user_id: "user04", age: 20, status: "A" },
...   { user_id: "abcd01", age: 28, status: "B" }
... ]
... )
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("62aea327254abf95397dcbc8"),
                ObjectId("62aea327254abf95397dcbc9"),
                ObjectId("62aea327254abf95397dcbca"),
                ObjectId("62aea327254abf95397dcbcb"),
                ObjectId("62aea327254abf95397dcbcc")
        ]
}

 

  →  Document 조회

rs0:PRIMARY> db.employees.find()
{ "_id" : ObjectId("62aea327254abf95397dcbc8"), "user_id" : "user01", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("62aea327254abf95397dcbc9"), "user_id" : "user02", "age" : 35, "status" : "A" }
{ "_id" : ObjectId("62aea327254abf95397dcbca"), "user_id" : "user03", "age" : 25, "status" : "B" }
{ "_id" : ObjectId("62aea327254abf95397dcbcb"), "user_id" : "user04", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("62aea327254abf95397dcbcc"), "user_id" : "abcd01", "age" : 28, "status" : "B" }

 

  →  비교문법 설명

### 비교 문법 : equal , greater than , greater than equal , less than , less than or equal , not equal, nin
$eq     =    Matches values that are equal to a specified value.
$gt     >    Matches values that are greater than a specified value.
$gte    >=   Matches values that are greater than or equal to a specified value.
$in          Matches any of the values specified in an array.
$lt     <    Matches values that are less than a specified value.
$lte    <=   Matches values that are less than or equal to a specified value.
$ne     !=   Matches all values that are not equal to a specified value.
$nin         Matches none of the values specified in an array.

 

  →  DocumentDB VS RDBMS ANSI SQL 쿼리 비교

db.employees.find() - SELECT * FROM people
db.employees.find({ }, { user_id: 1, status: 1 }) - SELECT _id, user_id, status FROM people
db.employees.find({ },{ user_id: 1, status: 1, _id: 0 }) - SELECT user_id, status FROM people
db.employees.find({ status: "A" }) - SELECT * FROM people WHERE status = "A"
db.employees.find({ status: "A", age: 20 }) - SELECT * FROM people WHERE status = "A" AND age = 20
db.employees.find({ $or: [ { status: "A" } , { age: 25 } ] }) - SELECT * FROM people WHERE status = "A" OR age = 25
db.employees.find({ age: { $gt: 25 } }) - SELECT * FROM people WHERE age > 25
db.employees.find({ age: { $lt: 25 } }) - SELECT * FROM people WHERE age < 25
db.employees.find({ age: { $gt: 25, $lte: 50 } }) - SELECT * FROM people WHERE age > 25 AND age <= 50
db.employees.find( { user_id: /use/ } )
db.employees.find( { user_id: { $regex: /use/ } } )   - SELECT * FROM people WHERE user_id like "%use%"
db.employees.find( { user_id: /^use/ } )
db.employees.find( { user_id: { $regex: /^use/ } } )    - SELECT * FROM people WHERE user_id like "use%"
db.employees.find( { status: "A" } ).sort( { user_id: 1 } ) - SELECT * FROM people WHERE status = "A" ORDER BY user_id ASC 
db.employees.find( { status: "A" } ).sort( { user_id: -1 } ) - SELECT * FROM people WHERE status = "A" ORDER BY user_id DESC
db.employees.find().count()  - SELECT COUNT(*) FROM people
db.employees.count()
db.employees.count( { user_id: { $exists: true } } )
db.employees.find( { user_id: { $exists: true } } ).count()  - SELECT COUNT(user_id) FROM people
db.employees.count( { age: { $gt: 30 } } )
db.employees.find( { age: { $gt: 30 } } ).count()  - SELECT COUNT(*) FROM people WHERE age > 30
db.employees.distinct( "status" ) - SELECT DISTINCT(status) FROM people
db.employees.findOne()
db.employees.find().limit(1)           - SELECT * FROM people LIMIT 1

 

 

  UPDATE : $set: field 값 설정

  →  UPDATE 전 도큐먼트 확인

rs0:PRIMARY> db.employees.find({}, {_id:0})
{ "user_id" : "user01", "age" : 45, "status" : "B" }
{ "user_id" : "user02", "age" : 35, "status" : "B" }
{ "user_id" : "user03", "age" : 25, "status" : "B" }
{ "user_id" : "user04", "age" : 20, "status" : "A" }
{ "user_id" : "abcd01", "age" : 28, "status" : "B" }

 

  →  UPDATE 전 도큐먼트 확인

rs0:PRIMARY> db.employees.updateMany( { age: {$gt: 30} }, { $set: {status: "E"} } )
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

 

  →  UPDATE 후 도큐먼트 확인

rs0:PRIMARY> db.employees.find({}, {_id:0})
{ "user_id" : "user01", "age" : 45, "status" : "E" }
{ "user_id" : "user02", "age" : 35, "status" : "E" }
{ "user_id" : "user03", "age" : 25, "status" : "B" }
{ "user_id" : "user04", "age" : 20, "status" : "A" }
{ "user_id" : "abcd01", "age" : 28, "status" : "B" }

 

  DELETE

  →  DELETE 전 도큐먼트 확인

rs0:PRIMARY> db.employees.find({}, {_id:0})
{ "user_id" : "user01", "age" : 45, "status" : "E" }
{ "user_id" : "user02", "age" : 35, "status" : "E" }
{ "user_id" : "user03", "age" : 25, "status" : "B" }
{ "user_id" : "user04", "age" : 20, "status" : "A" }
{ "user_id" : "abcd01", "age" : 28, "status" : "B" }

 

  →  삭제1 : DELETE FROM people WHERE status = "A" ;

rs0:PRIMARY> db.employees.deleteMany( { status: "A" } )  
{ "acknowledged" : true, "deletedCount" : 1 }

 

  →  도큐먼트 조회

rs0:PRIMARY> db.employees.find({}, {_id:0})
{ "user_id" : "user01", "age" : 45, "status" : "E" }
{ "user_id" : "user02", "age" : 35, "status" : "E" }
{ "user_id" : "user03", "age" : 25, "status" : "B" }
{ "user_id" : "abcd01", "age" : 28, "status" : "B" }

 

  →  삭제2  : DELETE FROM people ; 

rs0:PRIMARY> db.employees.deleteMany({})  
{ "acknowledged" : true, "deletedCount" : 4 }

 

  →  도큐먼트 조회

rs0:PRIMARY> db.employees.find({}, {_id:0})
rs0:PRIMARY>

 

콜렉션 삭제하기 : DROP TABLE EMPOLYEES ; 

rs0:PRIMARY> db.employees.drop()
true