본문 바로가기

공부기록/Mongodb

[mongoose]초기 설정

Schema 정의하기

https://mongoosejs.com/docs/guide.html#definition

몽구스에 있는 모든것은 Schema로 시작한다. 

각각의 shema들은 MongoDB collection에  연결되어있고, 

그 collection안에서 문서의 모양을 정의한다.

 

import mongoose from 'mongoose';
const { Schema } = mongoose;

const blogSchema = new Schema({
  title: String, // String is shorthand for {type: String}
  author: String,
  body: String,
  comments: [{ body: String, date: Date }],
  date: { type: Date, default: Date.now },
  hidden: Boolean,
  meta: {
    votes: Number,
    favs: Number
  }
});

blogSchema의 각 key는 연관된 SchemaType에 던져질 우리 문서 내부의 속성을 정의한다. 

 

만일 type한가지만 필요하다면 위 예시의 title key처럼 단축속성으로 정의할 수 있다. 

반면 date key는 아니다. 

중복된 object로도 정의할 수 있다. 

 

type key

type은 Mongoose schemas의 특별한 속성이다. mongoose가 중첩되어있는 type을 schema에서 발견하면 

주어진 타입으로 schema type을 정의할 필요가 있다는 것을 가정할 것이다. 

 

 

// 3 string SchemaTypes: 'name', 'nested.firstName', 'nested.lastName'
const schema = new Schema({
  name: { type: String },
  nested: {
    firstName: { type: String },
    lastName: { type: String }
  }
});

 

만일 중첩되어있는 key의 type이라는 속성을 따로 생성하고 싶다면 어떻게 해야할까?

아래와 같이 하면 된다. 

const holdingSchema = new Schema({
  asset: {
    // Workaround to make sure Mongoose knows `asset` is an object
    // and `asset.type` is a string, rather than thinking `asset`
    // is a string.
    type: { type: String },
    ticker: String
  }
});

 

허용되는 Schema type

모든 스키마 타입들

 

 

모델 생성

https://mongoosejs.com/docs/guide.html#models

Schema 정의를 사용하려면 위의 blogSchema를 Model로 변경해야 한다.

 

const Blog = mongoose.model('Blog', blogSchema);

 

schema에서 mongoose.model을 부를때 mongoose는 우리를 위해 모델을 쌓아준다. 

mongoose는 복수의, 소문자 버전의 model 이름을 찾는다. 

아래 예시에서는 데이터베이스의 컬렉션 중 tanks라는 이름을 가지고 있는 것이 model Tank이다. 

 

const schema = new mongoose.Schema({ name: String, size: String });
const Tank = mongoose.model('Tank', schema);

 

* 중요 : .model()함수는 schema의 복사본을 만들어준다. 

.model()을 부르기 전에 schema에 원하는 모든 것을 반드시 추가해야 한다. 

 

id

https://mongoosejs.com/docs/guide.html#_id

 mongoose는 기본적으로 _id 속성을 우리의 schema에 추가해준다.

type은 ObjectId가 된다. 

 

const schema = new Schema();

schema.path('_id'); // ObjectId { ... }

 

schema.path메서드

https://mongoosejs.com/docs/api/schema.html#Schema.prototype.path()

 

schema.path메서드는 인자로 주어진 path의 인스턴스된 schema type을 반환해준다.

schema type을 변경해주려고 할 때는 아래와 같이 두번째 인자에 type을 주면 된다.

 

schema.path('name') // returns a SchemaType
schema.path('name', Number) // changes the schemaType of `name` to Number

 

직접 _id속성을 덮어쓰기 할 수도 있으나, 그럴 때 _id가 없는 경우에는 저장하기를 거절할 것이므로 유의해야 한다.

 

const Model = mongoose.model('Test', schema);

const doc = new Model();
doc._id instanceof mongoose.Types.ObjectId; // true

 

 

 

인스턴스 메소드

https://mongoosejs.com/docs/guide.html#methods

model의 인스턴스들은 문서다. 문서는 많은 자신만의 빌트인 인스턴스 메소드를 많이 가지고 있다.

우리만의 커스텀 인스턴스 메소드를 정의할 수 있는 것이다. 

 

// define a schema
const animalSchema = new Schema({ name: String, type: String },
  {
  // Assign a function to the "methods" object of our animalSchema through schema options.
  // By following this approach, there is no need to create a separate TS type to define the type of the instance functions.
    methods: {
      findSimilarTypes(cb) {
        return mongoose.model('Animal').find({ type: this.type }, cb);
      }
    }
  });

// Or, assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function(cb) {
  return mongoose.model('Animal').find({ type: this.type }, cb);
};

schema 옵션을 통해 methods object라는 animalSchema의 object를 할당할 수 있다. 

인스턴스 함수의 타입을 따로 TS타입으로 생성할 필요는 없다. 

 

 

const Animal = mongoose.model('Animal', animalSchema);
const dog = new Animal({ type: 'dog' });

dog.findSimilarTypes((err, dogs) => {
  console.log(dogs); // woof
});

 

 

SchemaType.prototype.default() 

https://mongoosejs.com/docs/api/schematype.html#SchemaType.prototype.default()

 

// values are cast:
const schema = new Schema({ aNumber: { type: Number, default: 4.815162342 }})
const M = db.model('M', schema)
const m = new M;
console.log(m.aNumber) // 4.815162342

// default unique objects for Mixed types:
const schema = new Schema({ mixed: Schema.Types.Mixed });
schema.path('mixed').default(function () {
  return {};
});

// if we don't use a function to return object literals for Mixed defaults,
// each document will receive a reference to the same object literal creating
// a "shared" object instance:
const schema = new Schema({ mixed: Schema.Types.Mixed });
schema.path('mixed').default({});
const M = db.model('M', schema);
const m1 = new M;
m1.mixed.added = 1;
console.log(m1.mixed); // { added: 1 }
const m2 = new M;
console.log(m2.mixed); // { added: 1 }

 

 

mongoose.connect()로  mongoDB에 연결하기 

mongoose.connect('mongodb://127.0.0.1:27017/myapp');

 

mongoose는 mongoose가 mongoDB로의 연결을 수립하는걸 기다리지 않고

모델을 즉각적으로 사용하게 한다.

 

mongoose bufers 모델 함수가 내부적으로 실행되기 때문이다. 

편리하지만 약간의 혼란을 줄 수있다. 

기본적으로 연결이 없이 모델을 사용하더라도 에러를 내뿜지 않을 것이다. 

 

mongoose connection error handling 두가지 방법

 

mongoose.connect('mongodb://127.0.0.1:27017/test').
  catch(error => handleError(error));

// Or:
try {
  await mongoose.connect('mongodb://127.0.0.1:27017/test');
} catch (error) {
  handleError(error);
}

 

초기 커넥션이 완료된 후 error events listen하기

mongoose.connection.on('error', err => {
  logError(err);
});

 

 

Documents 구성하기 

model의 인스턴스를 document라고 부른다.

document를 만들고 database에 저장하는 것은 매우 간단하다. 

 

아래의 예시에서

model이 사용하고 있는 connection이 열려있을 때는 

tank 중 아무것도 삭제되거나 추가되지 않는다. 

모든 model은 connection이 결합되어있다. 

mongoose.model()을 사용하면 기본적인 mongoose connection을 사용할 것이다. 

const Tank = mongoose.model('Tank', yourSchema);

const small = new Tank({ size: 'small' });
await small.save();

// or

await Tank.create({ size: 'small' });

// or, for inserting large batches of documents
await Tank.insertMany([{ size: 'small' }]);

 

 

또다른 커스텀 커넥션을 만들고 싶으면 connection의 모델 함수를 사용하면 된다. 

 

const connection = mongoose.createConnection('mongodb://127.0.0.1:27017/test');
const Tank = connection.model('Tank', yourSchema);

 

 

질의하기 (Querying)

 

await Tank.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec();

 

mongoose의 query

mongoose model은 CRUD operation의 정적 헬퍼 함수를 제공해준다. 

https://mongoosejs.com/docs/queries.html

실행 Executing

쿼리를 실행할 때 Query를 JSON 문서로 명시해야 한다. 

mongoDB shell 과 JSON 문서의 문법은 동일하다. 

 

const Person = mongoose.model('Person', yourSchema);

// find each person with a last name matching 'Ghost', selecting the `name` and `occupation` fields
const person = await Person.findOne({ 'name.last': 'Ghost' }, 'name occupation');
// Prints "Space Ghost is a talk show host".
console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation);

 

 

 

 

'공부기록 > Mongodb' 카테고리의 다른 글

mongodb 툴 compass 설치하기 (Ubuntu)와 초기설정  (0) 2023.04.14
mongodb 초기설정하기  (0) 2023.04.14