. 특정 컬렉션에 대한 접근 제한 설정

MongoDB에서는 특정 컬렉션에 직접적으로 접근을 제한하는 내장 기능을 제공하지 않습니다. 하지만, 역할 기반의 접근 제어(Role-Based Access Control, RBAC)를 사용하여 사용자 정의 역할을 생성하고, 이 역할을 통해 특정 컬렉션에 대한 접근을 제어할 수 있습니다.

먼저, mydatabase 데이터베이스에서 사용자 정의 역할을 생성합니다.

 

use mydatabase
db.createRole({
  role: "collectionReadWrite",
  privileges: [
    { resource: { db: "mydatabase", collection: "mycollection" }, actions: ["find", "update", "insert", "remove"] }
  ],
  roles: []
})

 

그런 다음, 이 역할을 사용자에게 할당합니다

 

db.updateUser("myUser", {
  roles: [
    { role: "collectionReadWrite", db: "mydatabase" }
  ]
})

 

 

======== 사전에 mongoDB에 사용자가 설정되지 않았다면 다음스텝 필요==========

1. MongoDB 인증 활성화

먼저 MongoDB 서버에서 인증을 활성화해야 합니다. 이는 위에서 설명한

 

mongod.conf 파일을 편집하여 security.authorization 옵션을 enabled로 설정함으로써 이루어집니다. 서버 재시작 후 인증이 필요하게 됩니다.

 

security:
  authorization: enabled

 

2. 관리자 생성

$ mongo

> use admin
> db.createUser({
  user: "admin",
  pwd: "password",
  roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})

 

==> 모든 db에 비번에 필요할듯함. 

 

 

2.1 위에서 설명한 사용자 생성.

3. Spring Boot 애플리케이션 설정 변경

기존에 인증 없이 연결하던 Spring Boot 애플리케이션의 MongoDB 연결 설정을 업데이트하여 사용자 이름과 비밀번호를 포함하도록 해야 합니다. application.properties 또는 application.yml 파일에서 MongoDB 연결 URI를 다음과 같이 수정합니다:

 

# application.properties
spring.data.mongodb.uri=mongodb://username:password@host:port/database

Posted by yongary
,

 

mongoDB의 CSFLE라고 불리는 필드암호화는 mongoDB 4.2이상에서 지원된다.

(단, mongoDB enterprise에서만 지원된다)

 

스텝별로 살펴보면 다음과 같다.

 

1. KMS 서비스를 통해 key 생성. (아래는 AWS KMS이용 예제이지만,  azure의 keyVault나 Google Cloud KMS도 가능)

 

AWS Management Console에 로그인하여 KMS 서비스로 이동합니다.
새로운 키 생성을 선택하고, 키 유형으로 "대칭"을 선택합니다.
키에 이름을 부여하고, 필요한 권한을 설정합니다.
IAM 정책 설정:

키 사용 권한을 가진 IAM 사용자 또는 역할을 생성합니다.
생성된 KMS 키에 대한 액세스 권한을 해당 IAM 사용자 또는 역할에 부여합니다.

 

2. MongoDB 설정에 ClientEncryptions  설정.

@Bean
public MongoClient mongoClient() {
    Map<String, Object> awsKmsProvider = Map.of(
        "accessKeyId", "<AWS_ACCESS_KEY_ID>",
        "secretAccessKey", "<AWS_SECRET_ACCESS_KEY>"
    );

    Map<String, Map<String, Object>> kmsProviders = Map.of("aws", awsKmsProvider);

    AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
            .keyVaultNamespace("admin.dataKeys")
            .kmsProviders(kmsProviders)
            .build();

    MongoClientSettings settings = MongoClientSettings.builder()
            .applyConnectionString(new ConnectionString(uri))
            .autoEncryptionSettings(autoEncryptionSettings)
            .build();
    return MongoClients.create(settings);
}

@Bean
public MongoTemplate mongoTemplate() throws Exception {
    return new MongoTemplate(mongoClient(), dbName);
}

 

3. entity class의 필드에 @Encrypted 적용 

 

@Document
public class User {
    @Encrypted
    private String sensitiveData;
    
    private String generalData;
}
Posted by yongary
,

mtools

mongoDB, redis 2023. 9. 5. 17:59

mtools를 통해 EXPLAIN과 같이 slow query를 분석할 수 있다.

/var/logs/mongod 

밑에 있는 로그 파일을 50mb 정도의 사이즈로 나눠서

mloginfo --queries --no-progressbar 쪼개진파일.log > slow_queries.txt
(mtools 파이썬 패키지 설치하면 mloginfo라는 executable 생깁니다)

하면 늦은 query를 분석할 수 있다. 

Posted by yongary
,

oracle DDL 예제

mongoDB, redis 2023. 8. 4. 10:31

*TABLESPACE 생성

CREATE TABLESPACE TS_BIZHOME
DATAFILE '저장위치' SIZE 500M
AUTOEXTEND ON NEXT 100M;
저장위치: '/app/ora19c/oradata/ORCL/ts_bizhome01.dbf'   ora19c와 ORCL은 변경가능성있음.유저생성, 테이블스페이스 권한 주기:
create user [id] identified by [pw] default tablespace 테이블스페이스명;
grant connect, resource (,dba) to [id];
(alter user [유저명] default tablespace [테이블스페이스이름] quota unlimited on users;)
commit;
참고 View:  GRANT CREATE VIEW TO userId; 

 

* DDL 예제. (TB_C_GRPCODE, TB_C_DTLCODE)
CREATE TABLE TB_C_DTLCODE
(
GRP_CD CHAR(2) NOT NULL ,
DTL_CD VARCHAR2(2) NOT NULL ,
DTL_NM VARCHAR2(30) NOT NULL ,
BIGO VARCHAR2(100) NULL
);
CREATE UNIQUE INDEX TB_C_DTLCODE_PK ON TB_C_DTLCODE
(GRP_CD ASC,DTL_CD ASC);ALTER TABLE TB_C_DTLCODE
ADD CONSTRAINT TB_C_DTLCODE_PK PRIMARY KEY (GRP_CD,DTL_CD);CREATE TABLE TB_C_GRPCODE
(
GRP_CD CHAR(2) NOT NULL ,
GRP_NM VARCHAR2(30) NOT NULL
);CREATE UNIQUE INDEX TB_C_GRPCODE_PK ON TB_C_GRPCODE
(GRP_CD ASC);ALTER TABLE TB_C_GRPCODE
ADD CONSTRAINT TB_C_GRPCODE_PK PRIMARY KEY (GRP_CD);ALTER TABLE TB_C_DTLCODE
ADD (CONSTRAINT R_309 FOREIGN KEY (GRP_CD) REFERENCES TB_C_GRPCODE (GRP_CD));

Posted by yongary
,

aggregation중에 필드별  계산이 필요할 경우,  .andExpression을 통해 계산된 결과를 바로 받을 수 있고 이후에 조건/group도 가능핟.

// [select column]
ProjectionOperation projection = Aggregation.project()
        .and("gongsunGroup").as("gongsunGroup")
        .and("farmerNo").as("farmerNo")
        .and("pummokName").as("pummokName")
        .and("pumjongCode").as("pumjongCode")
        .and("rawReceivingDay").as("rawReceivingDay")
        .and("pboxCount").as("pboxCount")
        .andExpression("divide(floor(multiply(weight, 100)),100)").as("weight")
        ;

 

.andExpression과 비슷하지만 if 조건을 걸고 싶을 경우 (oracle에서 code였던가?)
.

ConditionalOperators 와
project에  .applyCondition(cond, field("nbE"))

을 사용하면 된다.  링크: https://yongary.tistory.com/420?category=539865 

Posted by yongary
,

 

[1.기본설치 - mongoDB 5.0 기준]

 

MongoDB 저장소 추가하기

1. MongoDB는 CentOS의 기본 저장소에 포함되어 있지 않으므로, 별도의 저장소를 추가해야 합니다. 다음 명령어를 터미널에서 실행하여 MongoDB 저장소를 추가합니다

 

$ sudo vi /etc/yum.repos.d/mongodb-org-5.0.repo

아래내용 입력 저장.

[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
 
2. 그 다음에 진짜 설치.
- $sudo yum install mongo-org

 

3. 설치 완료후 설정 수정.

- /etc/mongod.conf 에  bindIp를 0.0.0.0 으로 수정.

 

4. 시작 

- $sudo systemctl start mongod 
=> (start를  status로 고치거나, restart로 고치면, 상태조회, 재시작 가능.)

 

 

 

 

[2. replicaSet 설정 법]

https://docs.mongodb.com/manual/tutorial/deploy-replica-set/

  - /etc/mongod.conf 에 replication 추가 필요. [기본 3서버 설정 기준, =>  2서버 1가상 arbiter설정은 아래 참조]
replication:
   replSetName: "rs0" 

 

  • (sudo) service mongod start
  • 3대가 다 시작되면 그 중에 한대에 mongo 로 접속해서 아래명령 실행필요,
arbiter없을 경우:
  rs.initiate({
   _id : "rs0",
   members: [
      { _id: 0, host: "172.31.47.103:27017" },
      { _id: 1, host: "172.31.46.185:27017" },
      { _id: 2, host: "172.31.43.168:27017" }
   ]
})

arbiter있을 경우:
  rs.initiate({
   _id : "rs0",
   members: [
      { _id: 0, host: "172.31.47.103:27017" },
      { _id: 1, host: "172.31.46.185:27017" }
   ]
})

rs.conf() 및 rs.status()로 확인가능.

 

[2서버 1 아비터 설정시]

arbiter 세팅시에는, member2개로 rs.initiate하고 rs.addArb(“host:port”)를 수행.

https://thomassileo.name/blog/2012/03/08/how-to-mongodb-replica-sets/

그전에 arbiter 기동은 https://docs.mongodb.com/manual/tutorial/add-replica-set-arbiter/ 

1. $sudo mkdir -p /var/lib/mongodb/arb

2. $sudo mongod --dbpath /var/lib/mongodb/arb --replSet rs0 --bind_ip 0.0.0.0

 

 

priority변경 은: PRIMARY서버에 붙은 후

cfg = rs.conf()
cfg.members[0].priority = 0.5
cfg.members[1].priority = 1.0
cfg.members[2].priority = 0.5
rs.reconfig(cfg) 

 

Posted by yongary
,

1. aggregation시 조건부 sum을 하는 방법입니다.

https://stackoverflow.com/questions/41218321/grouping-and-sum-with-conditions

 

ConditionalOperators.Cond cond = when(Criteria.where("status").is("PRESENT")).then(1)
                .otherwise(when(Criteria.where("status").is("ABSENT")).then(2)
                .otherwise(100));
                
//ond operatorNbS = ConditionalOperators.when("scst").thenValueOf(1).otherwise(0);

Aggregation agg = newAggregation(
    match(Criteria.where("bid").is("build_1481711758"),
    project("bid") 
        .and("scst")                            
        .applyCondition(cond, field("nbE"))

 

2. aggregation시 substring을 이용한 조건부 sum을 하는 방법입니다.

https://recordsoflife.tistory.com/463

Posted by yongary
,

JSON Document

mongoDB, redis 2019. 12. 18. 23:52

Java class를 이용해서 mongoDB에 저장하면서 spring에서 지원하는 mongoTemplate을 쓰는게 가장 편한데,

 

가끔은 이 방법이 불편할 때가 있다.

 

Class가 Collection에 1:1 대응되지만,  Colletion에 필드가 너무 만은데

몇개만 front-End로 리턴해야 한다던지 하는 경우에 매우 불편할 수 있는데, 이럴때 좋은게 Json Document 이다.

 

주로 사용하게 되는 class는

      JSONObject, JSONArray   (net.minidev.json 패키지)

      Document  (mongoDB 저장된 record  org.bson 패키지)

이렇게 3가지 이며,

 

JSONObject <-> Document간 변환을 주로 하게된다.

 

1. Doc으로 변환 후 mongoDB에 저장시에는 

      (MongoDBConnection mongoConn). getCollection("컬렉션명").insertOne( oneDoc );      과 같이 하면 된다.

      Document doc = mongoConn.getCollection("...").find();  //or filter(new FIlter....).find()

2. Doc을 다룰 때 많이 쓰는 함수는 

    Document 생성.  doc.append

                    doc.get("fieldName") => Document가 되기도 하고 List<Document>가 되기도 하고 자동.  

 

 

기타: (JSONObject <-> Document간 변환용 함수들)

   
    public static Document jsonToDoc(JSONObject json) {
        try {
            Document doc = Document.parse(json.toString());
            return doc;
        } catch(Exception ex) {
            return null;
        }
    }

    public static ArrayList<Document> jsonArrayToDoc(JSONArray json) {
        try {
            final ArrayList<Document> result = new ArrayList<Document>();
            json.stream().map(obj -> (JSONObject)obj).forEach(item->result.add(jsonToDoc(item)));
            return result;
        } catch(Exception ex) {
            return null;
        }
    }
   public static JSONObject docToJson(Document doc) {
        JsonWriterSettings settings = JsonWriterSettings.builder()
                .int64Converter((value, writer) -> writer.writeNumber(value.toString()))
                .doubleConverter((value, writer) -> writer.writeNumber(Long.toString(Math.round(value))))
                .objectIdConverter((value, writer) -> writer.writeString(value.toHexString()))
                .build();
        return (JSONObject)JSONValue.parse(doc.toJson(settings));
    }

    public static JSONArray docToJsonArray(List<Document> docs) {
        JSONArray array = new JSONArray();
        for (Document doc : docs) {
            array.add(docToJson(doc));
        }
        return array;
    }

 

 

========  BigDecimal을 Document이용해  저장하는 경우 ============

- BigDecimal amount 몽고DB 저장 시
   document.append("amount", new Decimal128(amount)));

- BigDecimal amount 몽고DB 읽기 시
   amount = ((Decimal128) document.get("amount")).bigDecimalValue();

 

========vs. BigDecmial을  mongoTemplate을 이용해 저장하는 경우========

그냥 필드를 BigDecimal로 해 놓으면 자동으로 String처럼 변환되면서 mongoTemplate사용 가능할 것으로 예상.
안되면 https://stackoverflow.com/questions/37950296/spring-data-mongodb-bigdecimal-support참조. 

Posted by yongary
,

spring MongoDB

mongoDB, redis 2019. 9. 8. 12:47

 spring(boot)에서 mongoDB를 사용할 때, mongoTemplate으로 사용하면 controller와 service만으로 개발이 되므로 간단해서 주로 이 방법을 사용 중이다.

 

하지만, Repository를 사용할 경우 더 편리한 경우도 존재한다.

특히 @Query를 이용해 json형태의 query를 바로 사용할 수 있는 점이 가장 매력적이다.

 

기본적으로 mongoRepository를 상속만하면, 여러 조회함수들이 지원된다. 아래 링크 참조.

=> findByField + 조건

https://docs.spring.io/spring-data/mongodb/docs/1.2.0.RELEASE/reference/html/mongo.repositories.html 

 

6. MongoDB repositories

Most of the data access operations you usually trigger on a repository result a query being executed against the MongoDB databases. Defining such a query is just a matter of declaring a method on the repository interface The first method shows a query for

docs.spring.io

그 외 간단한 설정은 https://mommoo.tistory.com/79 참조.

 

@Query 사용방식은 https://www.devglan.com/spring-boot/spring-data-mongodb-queries 참조.

 

 

 

#spring #mongodb #@Query

Posted by yongary
,

sub-array를 일반document처럼 $unwind해서 사용하는 방법 추천.

 

그 외에는 아래 명령들을 사용하고

$elemMatch

$slice

 

(필요시) 최종적으로는 projection을 통해 sub-array가 있더라도 원하는 data를 조회할 수 있다.

 

 

마지막으로는 

variants.attrs 를 통해 추가적인 filter가 설정이 가능하다.  REF

 

Posted by yongary
,

mongo-java-driver

mongoDB, redis 2017. 7. 23. 23:16

javadoc_REF (많이쓸 클래스: async.client.mongoCollection)

             - 부속: async-driver

             <최근 dependency>

                'org.mongodb:mongo-java-driver:3.4.2'

       'org.mongodb:mongodb-driver-async:3.4.2'   



이중화: https://nextus.tistory.com/26


aggregate사용법:  기초 REF ,  프로그래밍 중에 사용법 REF

   aggretate상세설명: REF



Async Code예제:REF



JAVA (Spring에서 aggregation 사용예제)


Criteria criteria = new Criteria("producerNo").is(producerNo);

MatchOperation match = Aggregation.match(criteria);
SortOperation sort = Aggregation.sort(Sort.Direction.DESC, "deliverStart");
Aggregation agg = Aggregation.newAggregation(match, sort);

AggregationResults<DeliverProduct> results = mongoTemplate.aggregate(agg, "deliverProduct", DeliverProduct.class);
List<DeliverProduct> productList = results.getMappedResults();


  group의 경우

//SQL: db.xx.aggregate([{$group:{_id:{iotId:"$iotId", producerNo:"$producerNo"},
// deliverStart:{ $max:"$time"}}} ]

//RUN "group" Aggregation.//max(deliverStart)->deliverStart로
GroupOperation group = Aggregation.group("iotId", "producerNo").max("time").as("time");
Aggregation agg = Aggregation.newAggregation(group);



- 좀더 간단히 사용하려면 : REF (but, 추천은 아님)

Posted by yongary
,

기타 index

mongoDB, redis 2015. 11. 9. 17:47

mongoDB의 index는 메모리상의 working Set 에  Cache되어 관리된다.

working Set에는 index외에도, 데이타 일부가 cache되지만,   index가 우선 cache되어 성능향상을 시키는 구조이다.

 

 

데이타가: type: "restratunt"

loc: [ 37, 132 ] 일 경우,  

 

<2D index>

 

 

db.data..ensureIndex( {loc:'2d', type:1} )

 => $near 나  $maxDistance 가 사용가능하다. 

 

 

 

<2dsphere index>

 

db.data..ensureIndex( {loc:'2dsphere', type:1} )

=> $near 나 $maxDistance 가 사용가능하다.  $gemetry를 사용할 수 있다.

db.data.find( {loc: {  $near: {   $geomerty: { type: "restaurant",  coordinates:[38,127] },  $maxDistance:2000 }   }})

 

 

<text search index>

 

db.data..ensureIndex( {type:'text'} )

db.data.find( {'$text:{$search:'restaurant'}'} )          //$text앞에 '는 빼도 될듯.

 

 

Posted by yongary
,

<Index>

mongoDB에서 index 및 멀티index가 가능하다.

(default는 _Id 가 인덱스이다.)


<DB daata>

    db.nameage.find()

    { "_id" : ObjectId("561ddb57e8c49d6d56c71503"), "name" : "kim", "age" : 2 }


인덱스 추가시 

> db.nameage.ensureIndex( {name:1} )  or

db.nameage.createIndex( {name:1,  age:-1} )  // -1=descending.. compound index.

index show
db.nameage..getIndexes()

> db.namegae.dropIndex( {name:1} )


조회시 index  사용하는지 확인.
> db.nameage.find({name:"kim"}).explain()



MultiKey  index (for array index)  : age가 array라면 자동으로 MultiKey index 가 됨.

   - explain()해보면  isMultiKey: true라고 나옴.

    - name이 array라고 되고, age가 array라도 됨.

=> 단, name과 age 둘 다 array 로 doc insert하면.. insert 실패 남.


    -array 안에 subDoc이 있을 때, .(dot)을 사용해 index 생성가능. names:[  { country:"kor", name:"yong" }, { country:"nz", name:"gary"} ]

     db.nameage.createIndex( {names.name:1} )


     tip:  subDoc조회시에는 $elemMatch 사용가능.

    

Unique Index

   > db.nameage.createIndex( {name:1}, {unique:true}  )

   unique index를 만들면서, sparse 옵션을 주면  unique이긴 하지만, 그 필드가 없어도 된다.

 db.nameage.createIndex( {name:1}, {unique:true, sparse:true} )

    단, sparse index 일 경우, sort()명령에서는 index 사용을 못함.



<Storage Engine>


Mongo서버가---> StorageEngine을 통해서 --> disk에 접근.

MongoDB에는 2가지 storageEngine이 있다.


1. linux기본의  mmap  (이게 3.0에서도 default)

- collection 레벨 locking

- 2의 승수(power of 2) document 생성. (즉, 4,8,16,32  byte단위로 update여유 있게 생성)

2. WiredTiger ( 최근에 인수.)  mongoDB 3.0부터 지원,

        - document 레벨 locking

       -  압축 지원

       -  no in-place Update  (즉, update 하면 doc을 항상 추가함) : 이게 doc 레벨 lockding의 원동력임.

사용법:  시작시  $ mongod  -storageEngine wiredTiger             (-dbpath wT)

          

     

Posted by yongary
,

user collections에 data가 아래와 같을 때:

  {name:"kim", phone:{mobile:"010-1234", office:"02-1234" }}

  {name:"lee",  phone:{mobie:"010-2222", office:"02-2222" }}

 

Sub Document

>  db.user.find(  {phone:{mobile:"010-1234", office:"02-1234"}  } )       : mobile, office 순서가 일치해야지만 찾음. Exact match

 

result:  kim user 1 line.

>  db.user.find(  {phone:{mobile:"010-1234" }}) 

result: no result

 

Cursor

>  

cur=db.user.find();null;  (null 이 잠시대기함)> while (cur.hasNext()) printjson(cur.next());

result: all 2users. 2 line
 
 ( Doc 조회 이전 or empty일 때,  설정 가능한 작업들)
> cur.sort( {name:-1}  );null;                       //  reverse order -> return new Cursor. so need null;

> cur.sort( {name:-1}  ).limit(3); ;null;     // limit 3. -> return new Cursor. so need null;

 

update

대표예제:  db.b2bRawCncity.updateMany({cmId:{$gt:240400007}}, {$set:{cmId:null}} );

 

>  db.user.update(  {name:"kim"},   { name:"kim2"} )     //문서 전체 udpate. 

result:  kim->kim2  phone은 날아감. (disappear)

  $set

  >  db.user.update(  {name:"kim"},   { $set: { name:"kim2"} )  //just update

 result:  kim->kim2  phone remain.

  $unset

  >  db.user.update(  {name:"kim"},   { $unset: { phone:1} )

  field  phone remove

  $upsert : true   means  => 없을 때 insert 하라는 의미.

  $multi : true   means  => 여러건 update 할 때  필수. default는 한 건만 update.

 

$type:2    string을 의미함. bson의 저장방식으로 숫자마다 다른 type을 의미함.

 

 

Posted by yongary
,

user collections에 data가 아래와 같을 때:

  {name:"kim", food:["rice","water" ]}

  {name:"lee", food:["rice","orange" ]}

 

Field Display : _id는 default.

> db.user.find( {name:"kim"}, {food:false, _id:false } )

result: {"name":"kim"}

 

 

array

>  db.user.find( {food:"rice"} )       : array 1depth까지 바로 탐색.

result:  all user 2 line. 

  update array { $push (rightmost),  $pop:1(rightmost),       $pull (remove),  $addToSet(work like set) 

  >  db.user.update( {name:"kim", {food: { $pop:1}} )      

 

 

 

$or,

> db.user.find( { $or:[ { name:"kim"}, {name:"lee"} ] } )

 


$and

 and는 보통 필요가 없다.

> db.user.find( {name:"kim", food:"rice"}  ) ?

result: kim user 1 line. 


$regex, 

> db.user.find(  {name:  {$regex:" ^k"}   } )

result: kim user 1 line.


$exists (=field exists )

> db.user.find(  {name:  {$exists:true}   } )

result: all user 2line


$all,

> db.user.find ( {rice: {$all ["rice","water] }} )

result: kim user 1 line.


$in,  (sql 의 in과 유사)

> db.user.find ( {rice: {$in ["orange","water] }} )

result: all user 2 line.

Posted by yongary
,

mongoDB

mongoDB, redis 2015. 10. 13. 22:14

Functionality vs scalability&performance :

  -mongoDB achievs both. But missing some functionality because of scalibility&performance.


Not exists in mongoDB:

 -Join, transaction., schema, SQL


Exists in mongoDB:

  Index, secondary Index



Command:

  db

  show tables

  db.things.find ().pretty()

  db.things.insert (..json..)  or .save(json)


SchemaLess example:

> db.user.insert( {name:"kim"})

> db.user.insert( {name:"lee", age:11} )

> var j = db.user.findOne( {name:"kim"} )

> j.age = 11

> db.user.save(j)



Posted by yongary
,

$mongo 해서 client접속하면..

>show tables 


  //이 중에서  heart  category(테이블)을

  /user:"kim", pic:1, heart:20, date:'20140303'   이러한 테이블(category)로 가정.  (_id는 자동 삽입됨. _class도 간혹 자동삽입-코드일경우)



> db.heart.find()    -> 전체 record list.


> db.heart.find().sort( {pic:1} )    -> 전체 리스트를 pic필드로 asending 소팅.


> db.heart.find().limit(2)  -> 리스트 중 2개만 출력.   

                             =  db.heart.aggregate({ $limit:2 }) 


> db.heart.distinct("user")   ->  [ "kim", "lee" ]

> db.heart.distinct("user").length   ->   2



> db.heart.aggregate({     $group:{_id:"$pic"}      })  ->  pic필드를 기준으로 그루핑.  ({ => ([{ 이렇게 대괄호 추가가능.(이전버전인듯)


db.heart.aggregate({     $group:{ _id:"$pic", heartSum:{$sum:"$heart"} }      })  -> 각 그룹별로 heartSum산출.


   -->복합 aggregate

> db.heart.aggregate(    

{$group:{ _id:"$pic", heartSum:{$sum:"$heart"} }},

{$sort:{"hearts":1}},

{$limit:2}

)



//일반적인  Query .

db.inventory.find( { type: 'food', price: { $lt: 9.95 } } )



//aggregate에 Query  추가.

db.heart.aggregate(

bla.. bla..    ,

{ $match : { score : { $gt : 70, $lte : 90 } } }

)




///////spring-data-mongo에서 적용시에는

    AggregationOperation match = Aggregation.match(Criteria.where("service").is("EFT").and("source").is("MARKUP"));
    AggregationOperation group = Aggregation.group("card_acceptor").and("amount_sum").sum("amount").and("tran_count").count();
    Aggregation aggregation = newAggregation(match, group);
    AggregationResults<StoreSummary> result = this.mongoTemplate.aggregate(aggregation, "eft_transactions", StoreSummary.class);


Posted by yongary
,

redis를 사용하는 유명회사들에 대해선

redis.io 웹사이트에 다음과 같은 회사들이 언급되어 있다.


Blizzard에서 Wow 아바타 서비스에도 사용한다고 하는데 아직 확실치는 않다..

Posted by yongary
,

redis 실행법

mongoDB, redis 2014. 9. 16. 17:49

redis 설치 완료 후, src 폴더로 이동해서


1. stand-alone 모드 실행.

./redis-server  로 서버실행

./redis-cli  로 client 실행.

==> stand alone 모드로 default세팅 되어 실행된다.


reds> info          하면 정보 조회가능(데이타 개수도 있음)

redis>  keys *     하면 모든키 조회 가능(데이타가 많을경우는 조심)

 1)"MPx_TYPE_Audiox"  

 2)"FS_HB"

 3)"MP_TYPE_CTRL"
 4)"XCOD_ROOM_x"

 5)"CNFR_ROOM_x"

 

 



2. 마스터-슬레이브 모드

만약, master-slave모드로 테스트를 해보고 싶으면  redis-server를 아래명령으로 하나 더 실행한다.


$>./redis-server --port 6380 --slaveof 127.0.0.1 6379    



혹시, 이 상태에서 상태를 확인해보고 싶으면 client창에서


127.0.0.1:6379>  info  를 입력하면

#Replication 영역에

role:master

connected_slaves:1

      임을  을 확인할 수 있다.  즉 6379서버의 slave가 잘 뜬 것이다. 




3. Sentinel감시를 통한 HA 구성


위의 1,2번이 된 상태에서  아래와 같이 sentinel을 2개 정도 실행시키고....

$> src/redis-server sentinel1.conf --sentinel

$> src/redis-server sentinel2.conf --sentinel

==> 이러면 기본적인 HA완성.


이 때 1번 서버를 kill등으로 죽이면, 절체(HA)가 발생한다.


절체발생 후, 

client는 새로이 아래와 같은 명령으로 접속한다. 즉 2번 서버로 접속한다. 

$> redis-cli -p 6380  



ㅁ 좀 더 쉽게 절체를 발생시키는 방법은

redis-cli -p 26379 로 센티널로 cli접속을 한 다음에

>  sentinel failover mymaster    를 입력하면 바로 절체가 발생한다. 


  ( http://redis.io/topics/sentinel  참조)

  







 

Posted by yongary
,

간단히 NO-SQL 몇 개를 초급 수준에서 비교해 보았다. 


몽고DB :  Java를 이용하여 서버를 개발하는 인디/소호 개발의 관점에서 볼 때 최적!

  - json으로 DB에 기록을 해버리니, java개발자 입장에서는 java class가 바로 DB에 저장된다고 느낄 수 있다.
    (document 저장 방식이라고 부름)

 - geoSpace인덱싱이 매우 뛰어나서 혹시라도 지리적인 위치정보를 저장하는 경우, 조회에 관련된 많은 함수들이
    제공되고 속도도 빠르다. 지리 시스템이라면 초 강추!

 - 단점으로는 lock이 전체적으로 걸려서 write가 많은 시스템에선 비추라네요
  => (15.11월 글 참조) mongoDB3.0 부터는 wiredTiger엔진 사용시 row레벨lock(즉, document레벨락)지원.

 - Replication + failOver(장애복구)기능은 존재.

 - Clustering + 샤딩기능 : 존재하고, 확장(scaling or scale out)도 지원..    
     (참조:  http://yakoola.tistory.com/57 ) 


 Redis :  속도가 최우선인 시스템에 적합

   - 메모리 DB인 만큼 속도가 최우선시 되는 시스템에서 필수로 고려해야 한다.

    - 기초적인 사용법은 mySql수준이라서, 입문은 간단.

    - Replication 기능은 존재하지만 Async방식이라서 cluster상에서 일부 유실이 가능한 구조이다. 

    - failOver기능: 원래는 없었으나, 근래에는 sentinel기능이 도입되어 안정화 단계이다.

     - Clustering + 샤딩기능: 없으나 개발완료 단계이다. 올 여름 redis 3.0부터 배포가 되며, 16384개의 hash slot을
         미리 나눠좋고 샤딩을 하는 방식이다. 물론 slot조정이나 이동이 가능하다.
         (이전 버전에서는 clustering이 지원이 안되므로 zookeeper과 혼합해서 사용하는 방법이 혼용되었다)

 


Cassandra: 안정적인 시스템이며 write가 많은 초 대용량 시스템에 유리

      - 읽기보다 쓰기가 더 빠르다는데 시간을 재보진 않아서 믿지는 못하고 있지만
      -  Clustering기능이 뛰어나 안정된 시스템이라는 인상을 많이 준다. 



Posted by yongary
,